datapath: Use ether_addr_copy
authorJoe Perches <joe@perches.com>
Wed, 19 Feb 2014 19:08:50 +0000 (11:08 -0800)
committerPravin B Shelar <pshelar@nicira.com>
Sun, 16 Feb 2014 16:31:45 +0000 (08:31 -0800)
It's slightly smaller/faster for some architectures.

Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
datapath/actions.c
datapath/flow.c
datapath/flow_netlink.c
datapath/linux/compat/include/linux/etherdevice.h

index 30ea1d2..0b66e7c 100644 (file)
@@ -135,8 +135,8 @@ static int set_eth_addr(struct sk_buff *skb,
 
        skb_postpull_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);
 
-       memcpy(eth_hdr(skb)->h_source, eth_key->eth_src, ETH_ALEN);
-       memcpy(eth_hdr(skb)->h_dest, eth_key->eth_dst, ETH_ALEN);
+       ether_addr_copy(eth_hdr(skb)->h_source, eth_key->eth_src);
+       ether_addr_copy(eth_hdr(skb)->h_dest, eth_key->eth_dst);
 
        ovs_skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);
 
index 26af257..c3e3fcb 100644 (file)
@@ -400,14 +400,14 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
                            && opt_len == 8) {
                                if (unlikely(!is_zero_ether_addr(key->ipv6.nd.sll)))
                                        goto invalid;
-                               memcpy(key->ipv6.nd.sll,
-                                   &nd->opt[offset+sizeof(*nd_opt)], ETH_ALEN);
+                               ether_addr_copy(key->ipv6.nd.sll,
+                                   &nd->opt[offset+sizeof(*nd_opt)]);
                        } else if (nd_opt->nd_opt_type == ND_OPT_TARGET_LL_ADDR
                                   && opt_len == 8) {
                                if (unlikely(!is_zero_ether_addr(key->ipv6.nd.tll)))
                                        goto invalid;
-                               memcpy(key->ipv6.nd.tll,
-                                   &nd->opt[offset+sizeof(*nd_opt)], ETH_ALEN);
+                               ether_addr_copy(key->ipv6.nd.tll,
+                                   &nd->opt[offset+sizeof(*nd_opt)]);
                        }
 
                        icmp_len -= opt_len;
@@ -467,8 +467,8 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key)
         * header in the linear data area.
         */
        eth = eth_hdr(skb);
-       memcpy(key->eth.src, eth->h_source, ETH_ALEN);
-       memcpy(key->eth.dst, eth->h_dest, ETH_ALEN);
+       ether_addr_copy(key->eth.src, eth->h_source);
+       ether_addr_copy(key->eth.dst, eth->h_dest);
 
        __skb_pull(skb, 2 * ETH_ALEN);
        /* We are going to push all headers that we pull, so no need to
@@ -565,8 +565,8 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key)
                                key->ip.proto = ntohs(arp->ar_op);
                        memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src));
                        memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst));
-                       memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN);
-                       memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN);
+                       ether_addr_copy(key->ipv4.arp.sha, arp->ar_sha);
+                       ether_addr_copy(key->ipv4.arp.tha, arp->ar_tha);
                }
        } else if (key->eth.type == htons(ETH_P_IPV6)) {
                int nh_len;             /* IPv6 Header + Extensions */
index 3024a61..40751cb 100644 (file)
@@ -936,8 +936,8 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey,
                goto nla_put_failure;
 
        eth_key = nla_data(nla);
-       memcpy(eth_key->eth_src, output->eth.src, ETH_ALEN);
-       memcpy(eth_key->eth_dst, output->eth.dst, ETH_ALEN);
+       ether_addr_copy(eth_key->eth_src, output->eth.src);
+       ether_addr_copy(eth_key->eth_dst, output->eth.dst);
 
        if (swkey->eth.tci || swkey->eth.type == htons(ETH_P_8021Q)) {
                __be16 eth_type;
@@ -1009,8 +1009,8 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey,
                arp_key->arp_sip = output->ipv4.addr.src;
                arp_key->arp_tip = output->ipv4.addr.dst;
                arp_key->arp_op = htons(output->ip.proto);
-               memcpy(arp_key->arp_sha, output->ipv4.arp.sha, ETH_ALEN);
-               memcpy(arp_key->arp_tha, output->ipv4.arp.tha, ETH_ALEN);
+               ether_addr_copy(arp_key->arp_sha, output->ipv4.arp.sha);
+               ether_addr_copy(arp_key->arp_tha, output->ipv4.arp.tha);
        }
 
        if ((swkey->eth.type == htons(ETH_P_IP) ||
@@ -1097,8 +1097,8 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey,
                                nd_key = nla_data(nla);
                                memcpy(nd_key->nd_target, &output->ipv6.nd.target,
                                                        sizeof(nd_key->nd_target));
-                               memcpy(nd_key->nd_sll, output->ipv6.nd.sll, ETH_ALEN);
-                               memcpy(nd_key->nd_tll, output->ipv6.nd.tll, ETH_ALEN);
+                               ether_addr_copy(nd_key->nd_sll, output->ipv6.nd.sll);
+                               ether_addr_copy(nd_key->nd_tll, output->ipv6.nd.tll);
                        }
                }
        }
index eb7123e..556729d 100644 (file)
@@ -34,4 +34,19 @@ static inline int eth_mac_addr(struct net_device *dev, void *p)
 }
 #endif
 
+static inline void ether_addr_copy(u8 *dst, const u8 *src)
+{
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+       *(u32 *)dst = *(const u32 *)src;
+       *(u16 *)(dst + 4) = *(const u16 *)(src + 4);
+#else
+       u16 *a = (u16 *)dst;
+       const u16 *b = (const u16 *)src;
+
+       a[0] = b[0];
+       a[1] = b[1];
+       a[2] = b[2];
+#endif
+}
+
 #endif