Acked-by: Andy Zhou <az...@nicira.com>
On Wed, Sep 2, 2015 at 4:44 PM, Ben Pfaff <b...@nicira.com> wrote: > This allows the ARP cache to be prepopulated for testing purposes, so > that tests don't lose the first packet to each destination. (I guess > this feature could have other uses too.) > > Signed-off-by: Ben Pfaff <b...@nicira.com> > --- > lib/tnl-arp-cache.c | 67 > +++++++++++++++++++++++++++++------------ > ofproto/ofproto-tnl-unixctl.man | 4 +++ > 2 files changed, 52 insertions(+), 19 deletions(-) > > diff --git a/lib/tnl-arp-cache.c b/lib/tnl-arp-cache.c > index 3107631..ddfd26f 100644 > --- a/lib/tnl-arp-cache.c > +++ b/lib/tnl-arp-cache.c > @@ -30,6 +30,7 @@ > #include "packets.h" > #include "poll-loop.h" > #include "seq.h" > +#include "socket-util.h" > #include "timeval.h" > #include "tnl-arp-cache.h" > #include "unaligned.h" > @@ -95,28 +96,16 @@ tnl_arp_delete(struct tnl_arp_entry *arp) > ovsrcu_postpone(arp_entry_free, arp); > } > > -int > -tnl_arp_snoop(const struct flow *flow, struct flow_wildcards *wc, > - const char name[IFNAMSIZ]) > +static void > +tnl_arp_set(const char name[IFNAMSIZ], ovs_be32 dst, const struct eth_addr > mac) > { > - struct tnl_arp_entry *arp; > - > - 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); > - > ovs_mutex_lock(&mutex); > - arp = tnl_arp_lookup__(name, flow->nw_src); > + struct tnl_arp_entry *arp = tnl_arp_lookup__(name, dst); > if (arp) { > - if (eth_addr_equals(arp->mac, flow->arp_sha)) { > + if (eth_addr_equals(arp->mac, mac)) { > arp->expires = time_now() + ARP_ENTRY_DEFAULT_IDLE_TIME; > ovs_mutex_unlock(&mutex); > - return 0; > + return; > } > tnl_arp_delete(arp); > seq_change(tnl_conf_seq); > @@ -124,12 +113,29 @@ tnl_arp_snoop(const struct flow *flow, struct > flow_wildcards *wc, > > arp = xmalloc(sizeof *arp); > > - arp->ip = flow->nw_src; > - arp->mac = flow->arp_sha; > + 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, (OVS_FORCE uint32_t) arp->ip); > ovs_mutex_unlock(&mutex); > +} > + > +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; > } > > @@ -172,6 +178,28 @@ tnl_arp_cache_flush(struct unixctl_conn *conn, int argc > OVS_UNUSED, > unixctl_command_reply(conn, "OK"); > } > > +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 in_addr ip; > + > + if (lookup_ip(argv[2], &ip)) { > + 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, ip.s_addr, mac); > + unixctl_command_reply(conn, "OK"); > +} > + > #define MAX_IP_ADDR_LEN 17 > > static void > @@ -208,5 +236,6 @@ 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/ofproto/ofproto-tnl-unixctl.man b/ofproto/ofproto-tnl-unixctl.man > index 853b3f0..f9eb354 100644 > --- a/ofproto/ofproto-tnl-unixctl.man > +++ b/ofproto/ofproto-tnl-unixctl.man > @@ -18,6 +18,10 @@ Delete ipv4_address/plen route from OVS routing table. > OVS builds ARP cache by snooping are messages. This command shows > ARP cache table. > . > +.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/arp/flush\fR" > Flush ARP table. > . > -- > 2.1.3 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev