aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch')
-rw-r--r--net/openvswitch/actions.c4
-rw-r--r--net/openvswitch/datapath.c18
-rw-r--r--net/openvswitch/flow.c19
-rw-r--r--net/openvswitch/vport-internal_dev.c3
-rw-r--r--net/openvswitch/vport-netdev.c3
-rw-r--r--net/openvswitch/vport.c6
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,
158struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no) 158struct 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
400out: 400out:
@@ -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
1990static int __init dp_init(void) 1991static 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
490static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key, 492static 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)
98static void internal_dev_getinfo(struct net_device *netdev, 97static 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
104static const struct ethtool_ops internal_dev_ethtool_ops = { 103static 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 */
332void ovs_vport_receive(struct vport *vport, struct sk_buff *skb) 330void ovs_vport_receive(struct vport *vport, struct sk_buff *skb)
333{ 331{