diff options
Diffstat (limited to 'net/openvswitch')
-rw-r--r-- | net/openvswitch/actions.c | 4 | ||||
-rw-r--r-- | net/openvswitch/datapath.c | 18 | ||||
-rw-r--r-- | net/openvswitch/flow.c | 19 | ||||
-rw-r--r-- | net/openvswitch/vport-internal_dev.c | 3 | ||||
-rw-r--r-- | net/openvswitch/vport-netdev.c | 3 | ||||
-rw-r--r-- | net/openvswitch/vport.c | 6 |
6 files changed, 25 insertions, 28 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index ac2defeeba83..d4d5363c7ba7 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -58,7 +58,7 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci) | |||
58 | 58 | ||
59 | if (skb->ip_summed == CHECKSUM_COMPLETE) | 59 | if (skb->ip_summed == CHECKSUM_COMPLETE) |
60 | skb->csum = csum_sub(skb->csum, csum_partial(skb->data | 60 | skb->csum = csum_sub(skb->csum, csum_partial(skb->data |
61 | + ETH_HLEN, VLAN_HLEN, 0)); | 61 | + (2 * ETH_ALEN), VLAN_HLEN, 0)); |
62 | 62 | ||
63 | vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN); | 63 | vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN); |
64 | *current_tci = vhdr->h_vlan_TCI; | 64 | *current_tci = vhdr->h_vlan_TCI; |
@@ -115,7 +115,7 @@ static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vla | |||
115 | 115 | ||
116 | if (skb->ip_summed == CHECKSUM_COMPLETE) | 116 | if (skb->ip_summed == CHECKSUM_COMPLETE) |
117 | skb->csum = csum_add(skb->csum, csum_partial(skb->data | 117 | skb->csum = csum_add(skb->csum, csum_partial(skb->data |
118 | + ETH_HLEN, VLAN_HLEN, 0)); | 118 | + (2 * ETH_ALEN), VLAN_HLEN, 0)); |
119 | 119 | ||
120 | } | 120 | } |
121 | __vlan_hwaccel_put_tag(skb, ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT); | 121 | __vlan_hwaccel_put_tag(skb, ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT); |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index f996db343247..a4b724708a1a 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -158,11 +158,10 @@ static struct hlist_head *vport_hash_bucket(const struct datapath *dp, | |||
158 | struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no) | 158 | struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no) |
159 | { | 159 | { |
160 | struct vport *vport; | 160 | struct vport *vport; |
161 | struct hlist_node *n; | ||
162 | struct hlist_head *head; | 161 | struct hlist_head *head; |
163 | 162 | ||
164 | head = vport_hash_bucket(dp, port_no); | 163 | head = vport_hash_bucket(dp, port_no); |
165 | hlist_for_each_entry_rcu(vport, n, head, dp_hash_node) { | 164 | hlist_for_each_entry_rcu(vport, head, dp_hash_node) { |
166 | if (vport->port_no == port_no) | 165 | if (vport->port_no == port_no) |
167 | return vport; | 166 | return vport; |
168 | } | 167 | } |
@@ -301,7 +300,7 @@ static int queue_gso_packets(struct net *net, int dp_ifindex, | |||
301 | struct sk_buff *segs, *nskb; | 300 | struct sk_buff *segs, *nskb; |
302 | int err; | 301 | int err; |
303 | 302 | ||
304 | segs = skb_gso_segment(skb, NETIF_F_SG | NETIF_F_HW_CSUM); | 303 | segs = __skb_gso_segment(skb, NETIF_F_SG | NETIF_F_HW_CSUM, false); |
305 | if (IS_ERR(segs)) | 304 | if (IS_ERR(segs)) |
306 | return PTR_ERR(segs); | 305 | return PTR_ERR(segs); |
307 | 306 | ||
@@ -395,6 +394,7 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex, | |||
395 | 394 | ||
396 | skb_copy_and_csum_dev(skb, nla_data(nla)); | 395 | skb_copy_and_csum_dev(skb, nla_data(nla)); |
397 | 396 | ||
397 | genlmsg_end(user_skb, upcall); | ||
398 | err = genlmsg_unicast(net, user_skb, upcall_info->portid); | 398 | err = genlmsg_unicast(net, user_skb, upcall_info->portid); |
399 | 399 | ||
400 | out: | 400 | out: |
@@ -1386,9 +1386,9 @@ static void __dp_destroy(struct datapath *dp) | |||
1386 | 1386 | ||
1387 | for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) { | 1387 | for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) { |
1388 | struct vport *vport; | 1388 | struct vport *vport; |
1389 | struct hlist_node *node, *n; | 1389 | struct hlist_node *n; |
1390 | 1390 | ||
1391 | hlist_for_each_entry_safe(vport, node, n, &dp->ports[i], dp_hash_node) | 1391 | hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node) |
1392 | if (vport->port_no != OVSP_LOCAL) | 1392 | if (vport->port_no != OVSP_LOCAL) |
1393 | ovs_dp_detach_port(vport); | 1393 | ovs_dp_detach_port(vport); |
1394 | } | 1394 | } |
@@ -1691,6 +1691,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
1691 | if (IS_ERR(vport)) | 1691 | if (IS_ERR(vport)) |
1692 | goto exit_unlock; | 1692 | goto exit_unlock; |
1693 | 1693 | ||
1694 | err = 0; | ||
1694 | reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq, | 1695 | reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq, |
1695 | OVS_VPORT_CMD_NEW); | 1696 | OVS_VPORT_CMD_NEW); |
1696 | if (IS_ERR(reply)) { | 1697 | if (IS_ERR(reply)) { |
@@ -1772,6 +1773,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info) | |||
1772 | if (IS_ERR(reply)) | 1773 | if (IS_ERR(reply)) |
1773 | goto exit_unlock; | 1774 | goto exit_unlock; |
1774 | 1775 | ||
1776 | err = 0; | ||
1775 | ovs_dp_detach_port(vport); | 1777 | ovs_dp_detach_port(vport); |
1776 | 1778 | ||
1777 | genl_notify(reply, genl_info_net(info), info->snd_portid, | 1779 | genl_notify(reply, genl_info_net(info), info->snd_portid, |
@@ -1825,10 +1827,9 @@ static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
1825 | rcu_read_lock(); | 1827 | rcu_read_lock(); |
1826 | for (i = bucket; i < DP_VPORT_HASH_BUCKETS; i++) { | 1828 | for (i = bucket; i < DP_VPORT_HASH_BUCKETS; i++) { |
1827 | struct vport *vport; | 1829 | struct vport *vport; |
1828 | struct hlist_node *n; | ||
1829 | 1830 | ||
1830 | j = 0; | 1831 | j = 0; |
1831 | hlist_for_each_entry_rcu(vport, n, &dp->ports[i], dp_hash_node) { | 1832 | hlist_for_each_entry_rcu(vport, &dp->ports[i], dp_hash_node) { |
1832 | if (j >= skip && | 1833 | if (j >= skip && |
1833 | ovs_vport_cmd_fill_info(vport, skb, | 1834 | ovs_vport_cmd_fill_info(vport, skb, |
1834 | NETLINK_CB(cb->skb).portid, | 1835 | NETLINK_CB(cb->skb).portid, |
@@ -1989,10 +1990,9 @@ static struct pernet_operations ovs_net_ops = { | |||
1989 | 1990 | ||
1990 | static int __init dp_init(void) | 1991 | static int __init dp_init(void) |
1991 | { | 1992 | { |
1992 | struct sk_buff *dummy_skb; | ||
1993 | int err; | 1993 | int err; |
1994 | 1994 | ||
1995 | BUILD_BUG_ON(sizeof(struct ovs_skb_cb) > sizeof(dummy_skb->cb)); | 1995 | BUILD_BUG_ON(sizeof(struct ovs_skb_cb) > FIELD_SIZEOF(struct sk_buff, cb)); |
1996 | 1996 | ||
1997 | pr_info("Open vSwitch switching datapath\n"); | 1997 | pr_info("Open vSwitch switching datapath\n"); |
1998 | 1998 | ||
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index c3294cebc4f2..fe0e4215c73d 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -299,10 +299,10 @@ void ovs_flow_tbl_destroy(struct flow_table *table) | |||
299 | for (i = 0; i < table->n_buckets; i++) { | 299 | for (i = 0; i < table->n_buckets; i++) { |
300 | struct sw_flow *flow; | 300 | struct sw_flow *flow; |
301 | struct hlist_head *head = flex_array_get(table->buckets, i); | 301 | struct hlist_head *head = flex_array_get(table->buckets, i); |
302 | struct hlist_node *node, *n; | 302 | struct hlist_node *n; |
303 | int ver = table->node_ver; | 303 | int ver = table->node_ver; |
304 | 304 | ||
305 | hlist_for_each_entry_safe(flow, node, n, head, hash_node[ver]) { | 305 | hlist_for_each_entry_safe(flow, n, head, hash_node[ver]) { |
306 | hlist_del_rcu(&flow->hash_node[ver]); | 306 | hlist_del_rcu(&flow->hash_node[ver]); |
307 | ovs_flow_free(flow); | 307 | ovs_flow_free(flow); |
308 | } | 308 | } |
@@ -332,7 +332,6 @@ struct sw_flow *ovs_flow_tbl_next(struct flow_table *table, u32 *bucket, u32 *la | |||
332 | { | 332 | { |
333 | struct sw_flow *flow; | 333 | struct sw_flow *flow; |
334 | struct hlist_head *head; | 334 | struct hlist_head *head; |
335 | struct hlist_node *n; | ||
336 | int ver; | 335 | int ver; |
337 | int i; | 336 | int i; |
338 | 337 | ||
@@ -340,7 +339,7 @@ struct sw_flow *ovs_flow_tbl_next(struct flow_table *table, u32 *bucket, u32 *la | |||
340 | while (*bucket < table->n_buckets) { | 339 | while (*bucket < table->n_buckets) { |
341 | i = 0; | 340 | i = 0; |
342 | head = flex_array_get(table->buckets, *bucket); | 341 | head = flex_array_get(table->buckets, *bucket); |
343 | hlist_for_each_entry_rcu(flow, n, head, hash_node[ver]) { | 342 | hlist_for_each_entry_rcu(flow, head, hash_node[ver]) { |
344 | if (i < *last) { | 343 | if (i < *last) { |
345 | i++; | 344 | i++; |
346 | continue; | 345 | continue; |
@@ -367,11 +366,10 @@ static void flow_table_copy_flows(struct flow_table *old, struct flow_table *new | |||
367 | for (i = 0; i < old->n_buckets; i++) { | 366 | for (i = 0; i < old->n_buckets; i++) { |
368 | struct sw_flow *flow; | 367 | struct sw_flow *flow; |
369 | struct hlist_head *head; | 368 | struct hlist_head *head; |
370 | struct hlist_node *n; | ||
371 | 369 | ||
372 | head = flex_array_get(old->buckets, i); | 370 | head = flex_array_get(old->buckets, i); |
373 | 371 | ||
374 | hlist_for_each_entry(flow, n, head, hash_node[old_ver]) | 372 | hlist_for_each_entry(flow, head, hash_node[old_ver]) |
375 | ovs_flow_tbl_insert(new, flow); | 373 | ovs_flow_tbl_insert(new, flow); |
376 | } | 374 | } |
377 | old->keep_flows = true; | 375 | old->keep_flows = true; |
@@ -484,7 +482,11 @@ static __be16 parse_ethertype(struct sk_buff *skb) | |||
484 | return htons(ETH_P_802_2); | 482 | return htons(ETH_P_802_2); |
485 | 483 | ||
486 | __skb_pull(skb, sizeof(struct llc_snap_hdr)); | 484 | __skb_pull(skb, sizeof(struct llc_snap_hdr)); |
487 | return llc->ethertype; | 485 | |
486 | if (ntohs(llc->ethertype) >= 1536) | ||
487 | return llc->ethertype; | ||
488 | |||
489 | return htons(ETH_P_802_2); | ||
488 | } | 490 | } |
489 | 491 | ||
490 | static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key, | 492 | static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key, |
@@ -766,14 +768,13 @@ struct sw_flow *ovs_flow_tbl_lookup(struct flow_table *table, | |||
766 | struct sw_flow_key *key, int key_len) | 768 | struct sw_flow_key *key, int key_len) |
767 | { | 769 | { |
768 | struct sw_flow *flow; | 770 | struct sw_flow *flow; |
769 | struct hlist_node *n; | ||
770 | struct hlist_head *head; | 771 | struct hlist_head *head; |
771 | u32 hash; | 772 | u32 hash; |
772 | 773 | ||
773 | hash = ovs_flow_hash(key, key_len); | 774 | hash = ovs_flow_hash(key, key_len); |
774 | 775 | ||
775 | head = find_bucket(table, hash); | 776 | head = find_bucket(table, hash); |
776 | hlist_for_each_entry_rcu(flow, n, head, hash_node[table->node_ver]) { | 777 | hlist_for_each_entry_rcu(flow, head, hash_node[table->node_ver]) { |
777 | 778 | ||
778 | if (flow->hash == hash && | 779 | if (flow->hash == hash && |
779 | !memcmp(&flow->key, key, key_len)) { | 780 | !memcmp(&flow->key, key, key_len)) { |
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c index 5d460c37df07..0531de6c7a4a 100644 --- a/net/openvswitch/vport-internal_dev.c +++ b/net/openvswitch/vport-internal_dev.c | |||
@@ -69,7 +69,6 @@ static int internal_dev_mac_addr(struct net_device *dev, void *p) | |||
69 | 69 | ||
70 | if (!is_valid_ether_addr(addr->sa_data)) | 70 | if (!is_valid_ether_addr(addr->sa_data)) |
71 | return -EADDRNOTAVAIL; | 71 | return -EADDRNOTAVAIL; |
72 | dev->addr_assign_type &= ~NET_ADDR_RANDOM; | ||
73 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | 72 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); |
74 | return 0; | 73 | return 0; |
75 | } | 74 | } |
@@ -98,7 +97,7 @@ static int internal_dev_stop(struct net_device *netdev) | |||
98 | static void internal_dev_getinfo(struct net_device *netdev, | 97 | static void internal_dev_getinfo(struct net_device *netdev, |
99 | struct ethtool_drvinfo *info) | 98 | struct ethtool_drvinfo *info) |
100 | { | 99 | { |
101 | strcpy(info->driver, "openvswitch"); | 100 | strlcpy(info->driver, "openvswitch", sizeof(info->driver)); |
102 | } | 101 | } |
103 | 102 | ||
104 | static const struct ethtool_ops internal_dev_ethtool_ops = { | 103 | static const struct ethtool_ops internal_dev_ethtool_ops = { |
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index 670cbc3518de..2130d61c384a 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c | |||
@@ -43,8 +43,7 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb) | |||
43 | 43 | ||
44 | /* Make our own copy of the packet. Otherwise we will mangle the | 44 | /* Make our own copy of the packet. Otherwise we will mangle the |
45 | * packet for anyone who came before us (e.g. tcpdump via AF_PACKET). | 45 | * packet for anyone who came before us (e.g. tcpdump via AF_PACKET). |
46 | * (No one comes after us, since we tell handle_bridge() that we took | 46 | */ |
47 | * the packet.) */ | ||
48 | skb = skb_share_check(skb, GFP_ATOMIC); | 47 | skb = skb_share_check(skb, GFP_ATOMIC); |
49 | if (unlikely(!skb)) | 48 | if (unlikely(!skb)) |
50 | return; | 49 | return; |
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 70af0bedbac4..f6b8132ce4cb 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c | |||
@@ -86,9 +86,8 @@ struct vport *ovs_vport_locate(struct net *net, const char *name) | |||
86 | { | 86 | { |
87 | struct hlist_head *bucket = hash_bucket(net, name); | 87 | struct hlist_head *bucket = hash_bucket(net, name); |
88 | struct vport *vport; | 88 | struct vport *vport; |
89 | struct hlist_node *node; | ||
90 | 89 | ||
91 | hlist_for_each_entry_rcu(vport, node, bucket, hash_node) | 90 | hlist_for_each_entry_rcu(vport, bucket, hash_node) |
92 | if (!strcmp(name, vport->ops->get_name(vport)) && | 91 | if (!strcmp(name, vport->ops->get_name(vport)) && |
93 | net_eq(ovs_dp_get_net(vport->dp), net)) | 92 | net_eq(ovs_dp_get_net(vport->dp), net)) |
94 | return vport; | 93 | return vport; |
@@ -326,8 +325,7 @@ int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb) | |||
326 | * @skb: skb that was received | 325 | * @skb: skb that was received |
327 | * | 326 | * |
328 | * Must be called with rcu_read_lock. The packet cannot be shared and | 327 | * Must be called with rcu_read_lock. The packet cannot be shared and |
329 | * skb->data should point to the Ethernet header. The caller must have already | 328 | * skb->data should point to the Ethernet header. |
330 | * called compute_ip_summed() to initialize the checksumming fields. | ||
331 | */ | 329 | */ |
332 | void ovs_vport_receive(struct vport *vport, struct sk_buff *skb) | 330 | void ovs_vport_receive(struct vport *vport, struct sk_buff *skb) |
333 | { | 331 | { |