From: Thadeu Lima de Souza Cascardo Date: Mon, 30 Nov 2015 18:24:49 +0000 (-0200) Subject: tnl-arp-cache: Rename module and functions to tnl-neigh-cache. X-Git-Tag: v2.5.0~226 X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fovs.git;a=commitdiff_plain;h=53902038abe62c45ff46d7de9dcec30c3d1d861e tnl-arp-cache: Rename module and functions to tnl-neigh-cache. Since we don't distinguish between IPv4 and IPv6 lookups, consolidate ARP and ND cache into neighbor cache. Other references to ARP related to the ARP cache but that are not really about ARP have been renamed as well. tnl_arp_lookup is kept for lookups using IPv4 instead of IPv4-mapped addresses, but that is going to be removed in a later patch. Signed-off-by: Thadeu Lima de Souza Cascardo Signed-off-by: Ben Pfaff --- diff --git a/lib/automake.mk b/lib/automake.mk index d8c00da2c..b27a7176c 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -250,8 +250,8 @@ lib_libopenvswitch_la_SOURCES = \ lib/timer.h \ lib/timeval.c \ lib/timeval.h \ - lib/tnl-arp-cache.c \ - lib/tnl-arp-cache.h \ + lib/tnl-neigh-cache.c \ + lib/tnl-neigh-cache.h \ lib/tnl-ports.c \ lib/tnl-ports.h \ lib/token-bucket.c \ diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 4dcfded09..a67ef054d 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -64,7 +64,7 @@ #include "shash.h" #include "sset.h" #include "timeval.h" -#include "tnl-arp-cache.h" +#include "tnl-neigh-cache.h" #include "tnl-ports.h" #include "unixctl.h" #include "util.h" @@ -2555,7 +2555,7 @@ dpif_netdev_run(struct dpif *dpif) ovs_mutex_unlock(&dp->non_pmd_mutex); dp_netdev_pmd_unref(non_pmd); - tnl_arp_cache_run(); + tnl_neigh_cache_run(); tnl_port_map_run(); new_tnl_seq = seq_read(tnl_conf_seq); diff --git a/lib/dpif.c b/lib/dpif.c index 3d6ac6e0a..bcc407aff 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -44,7 +44,7 @@ #include "shash.h" #include "sset.h" #include "timeval.h" -#include "tnl-arp-cache.h" +#include "tnl-neigh-cache.h" #include "tnl-ports.h" #include "util.h" #include "uuid.h" @@ -122,7 +122,7 @@ dp_initialize(void) tnl_conf_seq = seq_create(); dpctl_unixctl_register(); tnl_port_map_init(); - tnl_arp_cache_init(); + tnl_neigh_cache_init(); route_table_init(); for (i = 0; i < ARRAY_SIZE(base_dpif_classes); i++) { diff --git a/lib/tnl-arp-cache.c b/lib/tnl-arp-cache.c deleted file mode 100644 index 75a6314e0..000000000 --- a/lib/tnl-arp-cache.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2014, 2015 Nicira, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "tnl-arp-cache.h" - -#include -#include -#include -#include -#include - -#include "bitmap.h" -#include "cmap.h" -#include "coverage.h" -#include "dpif-netdev.h" -#include "dynamic-string.h" -#include "errno.h" -#include "flow.h" -#include "netdev.h" -#include "ovs-thread.h" -#include "packets.h" -#include "poll-loop.h" -#include "seq.h" -#include "socket-util.h" -#include "timeval.h" -#include "unaligned.h" -#include "unixctl.h" -#include "util.h" -#include "openvswitch/vlog.h" - - -/* In seconds */ -#define ARP_ENTRY_DEFAULT_IDLE_TIME (15 * 60) - -struct tnl_arp_entry { - struct cmap_node cmap_node; - struct in6_addr ip; - struct eth_addr mac; - time_t expires; /* Expiration time. */ - char br_name[IFNAMSIZ]; -}; - -static struct cmap table; -static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; - -static uint32_t -tnl_arp_hash(const struct in6_addr *ip) -{ - return hash_bytes(ip->s6_addr, 16, 0); -} - -static struct tnl_arp_entry * -tnl_arp_lookup__(const char br_name[IFNAMSIZ], const struct in6_addr *dst) -{ - struct tnl_arp_entry *arp; - uint32_t hash; - - hash = tnl_arp_hash(dst); - CMAP_FOR_EACH_WITH_HASH (arp, cmap_node, hash, &table) { - if (ipv6_addr_equals(&arp->ip, dst) && !strcmp(arp->br_name, br_name)) { - arp->expires = time_now() + ARP_ENTRY_DEFAULT_IDLE_TIME; - return arp; - } - } - return NULL; -} - -int -tnl_arp_lookup(const char br_name[IFNAMSIZ], ovs_be32 dst, - struct eth_addr *mac) -{ - struct tnl_arp_entry *arp; - int res = ENOENT; - struct in6_addr dst6; - - in6_addr_set_mapped_ipv4(&dst6, dst); - - arp = tnl_arp_lookup__(br_name, &dst6); - if (arp) { - *mac = arp->mac; - res = 0; - } - - return res; -} - -int -tnl_nd_lookup(const char br_name[IFNAMSIZ], const struct in6_addr *dst, - struct eth_addr *mac) -{ - struct tnl_arp_entry *arp; - int res = ENOENT; - - arp = tnl_arp_lookup__(br_name, dst); - if (arp) { - *mac = arp->mac; - res = 0; - } - return res; -} - -static void -arp_entry_free(struct tnl_arp_entry *arp) -{ - free(arp); -} - -static void -tnl_arp_delete(struct tnl_arp_entry *arp) -{ - uint32_t hash = tnl_arp_hash(&arp->ip); - cmap_remove(&table, &arp->cmap_node, hash); - ovsrcu_postpone(arp_entry_free, arp); -} - -static void -tnl_arp_set__(const char name[IFNAMSIZ], const struct in6_addr *dst, - const struct eth_addr mac) -{ - ovs_mutex_lock(&mutex); - struct tnl_arp_entry *arp = tnl_arp_lookup__(name, dst); - if (arp) { - if (eth_addr_equals(arp->mac, mac)) { - arp->expires = time_now() + ARP_ENTRY_DEFAULT_IDLE_TIME; - ovs_mutex_unlock(&mutex); - return; - } - tnl_arp_delete(arp); - seq_change(tnl_conf_seq); - } - - arp = xmalloc(sizeof *arp); - - arp->ip = *dst; - arp->mac = mac; - arp->expires = time_now() + ARP_ENTRY_DEFAULT_IDLE_TIME; - ovs_strlcpy(arp->br_name, name, sizeof arp->br_name); - cmap_insert(&table, &arp->cmap_node, tnl_arp_hash(&arp->ip)); - ovs_mutex_unlock(&mutex); -} - -static void -tnl_arp_set(const char name[IFNAMSIZ], ovs_be32 dst, - const struct eth_addr mac) -{ - struct in6_addr dst6; - - in6_addr_set_mapped_ipv4(&dst6, dst); - tnl_arp_set__(name, &dst6, mac); -} - -int -tnl_arp_snoop(const struct flow *flow, struct flow_wildcards *wc, - const char name[IFNAMSIZ]) -{ - if (flow->dl_type != htons(ETH_TYPE_ARP)) { - return EINVAL; - } - - /* Exact Match on all ARP flows. */ - memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); - memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src); - memset(&wc->masks.arp_sha, 0xff, sizeof wc->masks.arp_sha); - - tnl_arp_set(name, flow->nw_src, flow->arp_sha); - return 0; -} - -int -tnl_nd_snoop(const struct flow *flow, struct flow_wildcards *wc, - const char name[IFNAMSIZ]) -{ - if (flow->dl_type != htons(ETH_TYPE_IPV6) || - flow->nw_proto != IPPROTO_ICMPV6 || - flow->tp_dst != htons(0) || - flow->tp_src != htons(ND_NEIGHBOR_ADVERT)) { - return EINVAL; - } - - memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src); - memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst); - memset(&wc->masks.nd_target, 0xff, sizeof wc->masks.nd_target); - memset(&wc->masks.arp_tha, 0xff, sizeof wc->masks.arp_tha); - - tnl_arp_set__(name, &flow->nd_target, flow->arp_tha); - return 0; -} - -void -tnl_arp_cache_run(void) -{ - struct tnl_arp_entry *arp; - bool changed = false; - - ovs_mutex_lock(&mutex); - CMAP_FOR_EACH(arp, cmap_node, &table) { - if (arp->expires <= time_now()) { - tnl_arp_delete(arp); - changed = true; - } - } - ovs_mutex_unlock(&mutex); - - if (changed) { - seq_change(tnl_conf_seq); - } -} - -static void -tnl_arp_cache_flush(struct unixctl_conn *conn, int argc OVS_UNUSED, - const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) -{ - struct tnl_arp_entry *arp; - bool changed = false; - - ovs_mutex_lock(&mutex); - CMAP_FOR_EACH(arp, cmap_node, &table) { - tnl_arp_delete(arp); - changed = true; - } - ovs_mutex_unlock(&mutex); - if (changed) { - seq_change(tnl_conf_seq); - } - unixctl_command_reply(conn, "OK"); -} - -static int -lookup_any(const char *host_name, struct in6_addr *address) -{ - if (addr_is_ipv6(host_name)) { - return lookup_ipv6(host_name, address); - } else { - int r; - struct in_addr ip; - r = lookup_ip(host_name, &ip); - if (r == 0) { - in6_addr_set_mapped_ipv4(address, ip.s_addr); - } - return r; - } - return ENOENT; -} - -static void -tnl_arp_cache_add(struct unixctl_conn *conn, int argc OVS_UNUSED, - const char *argv[], void *aux OVS_UNUSED) -{ - const char *br_name = argv[1]; - struct eth_addr mac; - struct in6_addr ip6; - - if (lookup_any(argv[2], &ip6) != 0) { - unixctl_command_reply_error(conn, "bad IP address"); - return; - } - - if (!eth_addr_from_string(argv[3], &mac)) { - unixctl_command_reply_error(conn, "bad MAC address"); - return; - } - - tnl_arp_set__(br_name, &ip6, mac); - unixctl_command_reply(conn, "OK"); -} - -static void -tnl_arp_cache_show(struct unixctl_conn *conn, int argc OVS_UNUSED, - const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) -{ - struct ds ds = DS_EMPTY_INITIALIZER; - struct tnl_arp_entry *arp; - - ds_put_cstr(&ds, "IP MAC Bridge\n"); - ds_put_cstr(&ds, "==========================================================================\n"); - ovs_mutex_lock(&mutex); - CMAP_FOR_EACH(arp, cmap_node, &table) { - int start_len, need_ws; - - start_len = ds.length; - ipv6_format_mapped(&arp->ip, &ds); - - need_ws = INET6_ADDRSTRLEN - (ds.length - start_len); - ds_put_char_multiple(&ds, ' ', need_ws); - - ds_put_format(&ds, ETH_ADDR_FMT" %s\n", - ETH_ADDR_ARGS(arp->mac), arp->br_name); - - } - ovs_mutex_unlock(&mutex); - unixctl_command_reply(conn, ds_cstr(&ds)); - ds_destroy(&ds); -} - -void -tnl_arp_cache_init(void) -{ - cmap_init(&table); - - unixctl_command_register("tnl/arp/show", "", 0, 0, tnl_arp_cache_show, NULL); - unixctl_command_register("tnl/arp/set", "BRIDGE IP MAC", 3, 3, tnl_arp_cache_add, NULL); - unixctl_command_register("tnl/arp/flush", "", 0, 0, tnl_arp_cache_flush, NULL); -} diff --git a/lib/tnl-arp-cache.h b/lib/tnl-arp-cache.h deleted file mode 100644 index 7620c15ac..000000000 --- a/lib/tnl-arp-cache.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2014 Nicira, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TNL_ARP_CACHE_H -#define TNL_ARP_CACHE_H 1 - -#include - -#include -#include -#include -#include -#include -#include - -#include "flow.h" -#include "netdev.h" -#include "packets.h" -#include "util.h" - -int tnl_arp_snoop(const struct flow *flow, struct flow_wildcards *wc, - const char dev_name[]); -int tnl_arp_lookup(const char dev_name[], ovs_be32 dst, struct eth_addr *mac); -void tnl_arp_cache_init(void); -void tnl_arp_cache_run(void); - -int tnl_nd_snoop(const struct flow *flow, struct flow_wildcards *wc, - const char dev_name[]); -int tnl_nd_lookup(const char dev_name[], const struct in6_addr *dst, - struct eth_addr *mac); - -#endif diff --git a/lib/tnl-neigh-cache.c b/lib/tnl-neigh-cache.c new file mode 100644 index 000000000..cf4082cb9 --- /dev/null +++ b/lib/tnl-neigh-cache.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2014, 2015 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "tnl-neigh-cache.h" + +#include +#include +#include +#include +#include + +#include "bitmap.h" +#include "cmap.h" +#include "coverage.h" +#include "dpif-netdev.h" +#include "dynamic-string.h" +#include "errno.h" +#include "flow.h" +#include "netdev.h" +#include "ovs-thread.h" +#include "packets.h" +#include "poll-loop.h" +#include "seq.h" +#include "socket-util.h" +#include "timeval.h" +#include "unaligned.h" +#include "unixctl.h" +#include "util.h" +#include "openvswitch/vlog.h" + + +/* In seconds */ +#define NEIGH_ENTRY_DEFAULT_IDLE_TIME (15 * 60) + +struct tnl_neigh_entry { + struct cmap_node cmap_node; + struct in6_addr ip; + struct eth_addr mac; + time_t expires; /* Expiration time. */ + char br_name[IFNAMSIZ]; +}; + +static struct cmap table; +static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; + +static uint32_t +tnl_neigh_hash(const struct in6_addr *ip) +{ + return hash_bytes(ip->s6_addr, 16, 0); +} + +static struct tnl_neigh_entry * +tnl_neigh_lookup__(const char br_name[IFNAMSIZ], const struct in6_addr *dst) +{ + struct tnl_neigh_entry *neigh; + uint32_t hash; + + hash = tnl_neigh_hash(dst); + CMAP_FOR_EACH_WITH_HASH (neigh, cmap_node, hash, &table) { + if (ipv6_addr_equals(&neigh->ip, dst) && !strcmp(neigh->br_name, br_name)) { + neigh->expires = time_now() + NEIGH_ENTRY_DEFAULT_IDLE_TIME; + return neigh; + } + } + return NULL; +} + +int +tnl_arp_lookup(const char br_name[IFNAMSIZ], ovs_be32 dst, + struct eth_addr *mac) +{ + struct tnl_neigh_entry *neigh; + int res = ENOENT; + struct in6_addr dst6; + + in6_addr_set_mapped_ipv4(&dst6, dst); + + neigh = tnl_neigh_lookup__(br_name, &dst6); + if (neigh) { + *mac = neigh->mac; + res = 0; + } + + return res; +} + +int +tnl_neigh_lookup(const char br_name[IFNAMSIZ], const struct in6_addr *dst, + struct eth_addr *mac) +{ + struct tnl_neigh_entry *neigh; + int res = ENOENT; + + neigh = tnl_neigh_lookup__(br_name, dst); + if (neigh) { + *mac = neigh->mac; + res = 0; + } + return res; +} + +static void +neigh_entry_free(struct tnl_neigh_entry *neigh) +{ + free(neigh); +} + +static void +tnl_neigh_delete(struct tnl_neigh_entry *neigh) +{ + uint32_t hash = tnl_neigh_hash(&neigh->ip); + cmap_remove(&table, &neigh->cmap_node, hash); + ovsrcu_postpone(neigh_entry_free, neigh); +} + +static void +tnl_neigh_set__(const char name[IFNAMSIZ], const struct in6_addr *dst, + const struct eth_addr mac) +{ + ovs_mutex_lock(&mutex); + struct tnl_neigh_entry *neigh = tnl_neigh_lookup__(name, dst); + if (neigh) { + if (eth_addr_equals(neigh->mac, mac)) { + neigh->expires = time_now() + NEIGH_ENTRY_DEFAULT_IDLE_TIME; + ovs_mutex_unlock(&mutex); + return; + } + tnl_neigh_delete(neigh); + seq_change(tnl_conf_seq); + } + + neigh = xmalloc(sizeof *neigh); + + neigh->ip = *dst; + neigh->mac = mac; + neigh->expires = time_now() + NEIGH_ENTRY_DEFAULT_IDLE_TIME; + ovs_strlcpy(neigh->br_name, name, sizeof neigh->br_name); + cmap_insert(&table, &neigh->cmap_node, tnl_neigh_hash(&neigh->ip)); + ovs_mutex_unlock(&mutex); +} + +static void +tnl_arp_set(const char name[IFNAMSIZ], ovs_be32 dst, + const struct eth_addr mac) +{ + struct in6_addr dst6; + + in6_addr_set_mapped_ipv4(&dst6, dst); + tnl_neigh_set__(name, &dst6, mac); +} + +static int +tnl_arp_snoop(const struct flow *flow, struct flow_wildcards *wc, + const char name[IFNAMSIZ]) +{ + if (flow->dl_type != htons(ETH_TYPE_ARP)) { + return EINVAL; + } + + /* Exact Match on all ARP flows. */ + memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto); + memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src); + memset(&wc->masks.arp_sha, 0xff, sizeof wc->masks.arp_sha); + + tnl_arp_set(name, flow->nw_src, flow->arp_sha); + return 0; +} + +static int +tnl_nd_snoop(const struct flow *flow, struct flow_wildcards *wc, + const char name[IFNAMSIZ]) +{ + if (flow->dl_type != htons(ETH_TYPE_IPV6) || + flow->nw_proto != IPPROTO_ICMPV6 || + flow->tp_dst != htons(0) || + flow->tp_src != htons(ND_NEIGHBOR_ADVERT)) { + return EINVAL; + } + + memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src); + memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst); + memset(&wc->masks.nd_target, 0xff, sizeof wc->masks.nd_target); + memset(&wc->masks.arp_tha, 0xff, sizeof wc->masks.arp_tha); + + tnl_neigh_set__(name, &flow->nd_target, flow->arp_tha); + return 0; +} + +int +tnl_neigh_snoop(const struct flow *flow, struct flow_wildcards *wc, + const char name[IFNAMSIZ]) +{ + int res; + res = tnl_arp_snoop(flow, wc, name); + if (res != EINVAL) { + return res; + } + return tnl_nd_snoop(flow, wc, name); +} + +void +tnl_neigh_cache_run(void) +{ + struct tnl_neigh_entry *neigh; + bool changed = false; + + ovs_mutex_lock(&mutex); + CMAP_FOR_EACH(neigh, cmap_node, &table) { + if (neigh->expires <= time_now()) { + tnl_neigh_delete(neigh); + changed = true; + } + } + ovs_mutex_unlock(&mutex); + + if (changed) { + seq_change(tnl_conf_seq); + } +} + +static void +tnl_neigh_cache_flush(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) +{ + struct tnl_neigh_entry *neigh; + bool changed = false; + + ovs_mutex_lock(&mutex); + CMAP_FOR_EACH(neigh, cmap_node, &table) { + tnl_neigh_delete(neigh); + changed = true; + } + ovs_mutex_unlock(&mutex); + if (changed) { + seq_change(tnl_conf_seq); + } + unixctl_command_reply(conn, "OK"); +} + +static int +lookup_any(const char *host_name, struct in6_addr *address) +{ + if (addr_is_ipv6(host_name)) { + return lookup_ipv6(host_name, address); + } else { + int r; + struct in_addr ip; + r = lookup_ip(host_name, &ip); + if (r == 0) { + in6_addr_set_mapped_ipv4(address, ip.s_addr); + } + return r; + } + return ENOENT; +} + +static void +tnl_neigh_cache_add(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[], void *aux OVS_UNUSED) +{ + const char *br_name = argv[1]; + struct eth_addr mac; + struct in6_addr ip6; + + if (lookup_any(argv[2], &ip6) != 0) { + unixctl_command_reply_error(conn, "bad IP address"); + return; + } + + if (!eth_addr_from_string(argv[3], &mac)) { + unixctl_command_reply_error(conn, "bad MAC address"); + return; + } + + tnl_neigh_set__(br_name, &ip6, mac); + unixctl_command_reply(conn, "OK"); +} + +static void +tnl_neigh_cache_show(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) +{ + struct ds ds = DS_EMPTY_INITIALIZER; + struct tnl_neigh_entry *neigh; + + ds_put_cstr(&ds, "IP MAC Bridge\n"); + ds_put_cstr(&ds, "==========================================================================\n"); + ovs_mutex_lock(&mutex); + CMAP_FOR_EACH(neigh, cmap_node, &table) { + int start_len, need_ws; + + start_len = ds.length; + ipv6_format_mapped(&neigh->ip, &ds); + + need_ws = INET6_ADDRSTRLEN - (ds.length - start_len); + ds_put_char_multiple(&ds, ' ', need_ws); + + ds_put_format(&ds, ETH_ADDR_FMT" %s\n", + ETH_ADDR_ARGS(neigh->mac), neigh->br_name); + + } + ovs_mutex_unlock(&mutex); + unixctl_command_reply(conn, ds_cstr(&ds)); + ds_destroy(&ds); +} + +void +tnl_neigh_cache_init(void) +{ + cmap_init(&table); + + unixctl_command_register("tnl/arp/show", "", 0, 0, tnl_neigh_cache_show, NULL); + unixctl_command_register("tnl/arp/set", "BRIDGE IP MAC", 3, 3, tnl_neigh_cache_add, NULL); + unixctl_command_register("tnl/arp/flush", "", 0, 0, tnl_neigh_cache_flush, NULL); + unixctl_command_register("tnl/neigh/show", "", 0, 0, tnl_neigh_cache_show, NULL); + unixctl_command_register("tnl/neigh/set", "BRIDGE IP MAC", 3, 3, tnl_neigh_cache_add, NULL); + unixctl_command_register("tnl/neigh/flush", "", 0, 0, tnl_neigh_cache_flush, NULL); +} diff --git a/lib/tnl-neigh-cache.h b/lib/tnl-neigh-cache.h new file mode 100644 index 000000000..a9acd9ede --- /dev/null +++ b/lib/tnl-neigh-cache.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TNL_NEIGH_CACHE_H +#define TNL_NEIGH_CACHE_H 1 + +#include + +#include +#include +#include +#include +#include +#include + +#include "flow.h" +#include "netdev.h" +#include "packets.h" +#include "util.h" + +int tnl_neigh_snoop(const struct flow *flow, struct flow_wildcards *wc, + const char dev_name[]); +int tnl_neigh_lookup(const char dev_name[], const struct in6_addr *dst, + struct eth_addr *mac); +void tnl_neigh_cache_init(void); +void tnl_neigh_cache_run(void); + +int tnl_arp_lookup(const char dev_name[], ovs_be32 dst, struct eth_addr *mac); + +#endif diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 74ad26c30..dd98d6e81 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -22,7 +22,7 @@ #include #include -#include "tnl-arp-cache.h" +#include "tnl-neigh-cache.h" #include "bfd.h" #include "bitmap.h" #include "bond.h" @@ -399,7 +399,7 @@ enum xc_type { XC_NORMAL, XC_FIN_TIMEOUT, XC_GROUP, - XC_TNL_ARP, + XC_TNL_NEIGH, }; /* xlate_cache entries hold enough information to perform the side effects of @@ -452,7 +452,7 @@ struct xc_entry { struct { char br_name[IFNAMSIZ]; ovs_be32 d_ip; - } tnl_arp_cache; + } tnl_neigh_cache; } u; }; @@ -2810,10 +2810,10 @@ build_tunnel_send(struct xlate_ctx *ctx, const struct xport *xport, if (ctx->xin->xcache) { struct xc_entry *entry; - entry = xlate_cache_add_entry(ctx->xin->xcache, XC_TNL_ARP); - ovs_strlcpy(entry->u.tnl_arp_cache.br_name, out_dev->xbridge->name, - sizeof entry->u.tnl_arp_cache.br_name); - entry->u.tnl_arp_cache.d_ip = d_ip; + entry = xlate_cache_add_entry(ctx->xin->xcache, XC_TNL_NEIGH); + ovs_strlcpy(entry->u.tnl_neigh_cache.br_name, out_dev->xbridge->name, + sizeof entry->u.tnl_neigh_cache.br_name); + entry->u.tnl_neigh_cache.d_ip = d_ip; } xlate_report(ctx, "tunneling from "ETH_ADDR_FMT" "IP_FMT @@ -4356,8 +4356,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, const struct ofpact *a; if (ovs_native_tunneling_is_on(ctx->xbridge->ofproto)) { - tnl_arp_snoop(flow, wc, ctx->xbridge->name); - tnl_nd_snoop(flow, wc, ctx->xbridge->name); + tnl_neigh_snoop(flow, wc, ctx->xbridge->name); } /* dl_type already in the mask, not set below. */ @@ -5485,10 +5484,10 @@ xlate_push_stats(struct xlate_cache *xcache, group_dpif_credit_stats(entry->u.group.group, entry->u.group.bucket, stats); break; - case XC_TNL_ARP: - /* Lookup arp to avoid arp timeout. */ - tnl_arp_lookup(entry->u.tnl_arp_cache.br_name, - entry->u.tnl_arp_cache.d_ip, &dmac); + case XC_TNL_NEIGH: + /* Lookup neighbor to avoid timeout. */ + tnl_arp_lookup(entry->u.tnl_neigh_cache.br_name, + entry->u.tnl_neigh_cache.d_ip, &dmac); break; default: OVS_NOT_REACHED(); @@ -5560,7 +5559,7 @@ xlate_cache_clear(struct xlate_cache *xcache) case XC_GROUP: group_dpif_unref(entry->u.group.group); break; - case XC_TNL_ARP: + case XC_TNL_NEIGH: break; default: OVS_NOT_REACHED(); diff --git a/ofproto/ofproto-tnl-unixctl.man b/ofproto/ofproto-tnl-unixctl.man index f9eb35405..fa14b8765 100644 --- a/ofproto/ofproto-tnl-unixctl.man +++ b/ofproto/ofproto-tnl-unixctl.man @@ -14,14 +14,17 @@ from system routing table and user configured routes. .IP "\fBovs/route/del ipv4_address/plen\fR" Delete ipv4_address/plen route from OVS routing table. . +.IP "\fBtnl/neigh/show\fR" .IP "\fBtnl/arp/show\fR" OVS builds ARP cache by snooping are messages. This command shows ARP cache table. . +.IP "\fBtnl/neigh/set \fIbridge ip mac\fR" .IP "\fBtnl/arp/set \fIbridge ip mac\fR" Adds or modifies an ARP cache entry in \fIbridge\fR, mapping \fIip\fR to \fImac\fR. . +.IP "\fBtnl/neigh/flush\fR" .IP "\fBtnl/arp/flush\fR" Flush ARP table. . diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c index bd4e1dc5f..d1cf4bd15 100644 --- a/ofproto/tunnel.c +++ b/ofproto/tunnel.c @@ -33,7 +33,6 @@ #include "seq.h" #include "smap.h" #include "socket-util.h" -#include "tnl-arp-cache.h" #include "tnl-ports.h" #include "tunnel.h" #include "openvswitch/vlog.h" diff --git a/tests/ofproto-macros.at b/tests/ofproto-macros.at index 9b52cae45..bace0f518 100644 --- a/tests/ofproto-macros.at +++ b/tests/ofproto-macros.at @@ -225,7 +225,7 @@ ovn_populate_arp() { for e2 in $arp_table; do set `echo $e2 | sed 's/,/ /g'`; sb2=$1 br2=$2 if test $sb1,$br1 != $sb2,$br2; then - as $sb2 ovs-appctl tnl/arp/set $br2 $ip $mac + as $sb2 ovs-appctl tnl/neigh/set $br2 $ip $mac fi done done diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at index 507d4df31..618950f3c 100644 --- a/tests/tunnel-push-pop.at +++ b/tests/tunnel-push-pop.at @@ -40,7 +40,7 @@ dnl Check ARP Snoop AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=1,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)']) AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b7,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.93,tip=1.1.2.88,op=1,sha=f8:bc:12:44:34:b7,tha=00:00:00:00:00:00)']) -AT_CHECK([ovs-appctl tnl/arp/show], [0], [dnl +AT_CHECK([ovs-appctl tnl/neigh/show], [0], [dnl IP MAC Bridge ========================================================================== 1.1.2.92 f8:bc:12:44:34:b6 br0