aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch')
-rw-r--r--net/openvswitch/actions.c50
-rw-r--r--net/openvswitch/datapath.c55
-rw-r--r--net/openvswitch/datapath.h2
-rw-r--r--net/openvswitch/vport-internal_dev.c24
-rw-r--r--net/openvswitch/vport-internal_dev.h2
-rw-r--r--net/openvswitch/vport-vxlan.c5
-rw-r--r--net/openvswitch/vport.c101
-rw-r--r--net/openvswitch/vport.h27
8 files changed, 224 insertions, 42 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index e70d8b18e962..fe5cda0deb39 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -38,7 +38,7 @@
38#include "vport.h" 38#include "vport.h"
39 39
40static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, 40static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
41 const struct nlattr *attr, int len, bool keep_skb); 41 const struct nlattr *attr, int len);
42 42
43static int make_writable(struct sk_buff *skb, int write_len) 43static int make_writable(struct sk_buff *skb, int write_len)
44{ 44{
@@ -434,11 +434,17 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
434 return ovs_dp_upcall(dp, skb, &upcall); 434 return ovs_dp_upcall(dp, skb, &upcall);
435} 435}
436 436
437static bool last_action(const struct nlattr *a, int rem)
438{
439 return a->nla_len == rem;
440}
441
437static int sample(struct datapath *dp, struct sk_buff *skb, 442static int sample(struct datapath *dp, struct sk_buff *skb,
438 const struct nlattr *attr) 443 const struct nlattr *attr)
439{ 444{
440 const struct nlattr *acts_list = NULL; 445 const struct nlattr *acts_list = NULL;
441 const struct nlattr *a; 446 const struct nlattr *a;
447 struct sk_buff *sample_skb;
442 int rem; 448 int rem;
443 449
444 for (a = nla_data(attr), rem = nla_len(attr); rem > 0; 450 for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
@@ -455,8 +461,34 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
455 } 461 }
456 } 462 }
457 463
458 return do_execute_actions(dp, skb, nla_data(acts_list), 464 rem = nla_len(acts_list);
459 nla_len(acts_list), true); 465 a = nla_data(acts_list);
466
467 /* Actions list is either empty or only contains a single user-space
468 * action, the latter being a special case as it is the only known
469 * usage of the sample action.
470 * In these special cases don't clone the skb as there are no
471 * side-effects in the nested actions.
472 * Otherwise, clone in case the nested actions have side effects.
473 */
474 if (likely(rem == 0 || (nla_type(a) == OVS_ACTION_ATTR_USERSPACE &&
475 last_action(a, rem)))) {
476 sample_skb = skb;
477 skb_get(skb);
478 } else {
479 sample_skb = skb_clone(skb, GFP_ATOMIC);
480 if (!sample_skb) /* Skip sample action when out of memory. */
481 return 0;
482 }
483
484 /* Note that do_execute_actions() never consumes skb.
485 * In the case where skb has been cloned above it is the clone that
486 * is consumed. Otherwise the skb_get(skb) call prevents
487 * consumption by do_execute_actions(). Thus, it is safe to simply
488 * return the error code and let the caller (also
489 * do_execute_actions()) free skb on error.
490 */
491 return do_execute_actions(dp, sample_skb, a, rem);
460} 492}
461 493
462static int execute_set_action(struct sk_buff *skb, 494static int execute_set_action(struct sk_buff *skb,
@@ -507,7 +539,7 @@ static int execute_set_action(struct sk_buff *skb,
507 539
508/* Execute a list of actions against 'skb'. */ 540/* Execute a list of actions against 'skb'. */
509static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, 541static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
510 const struct nlattr *attr, int len, bool keep_skb) 542 const struct nlattr *attr, int len)
511{ 543{
512 /* Every output action needs a separate clone of 'skb', but the common 544 /* Every output action needs a separate clone of 'skb', but the common
513 * case is just a single output action, so that doing a clone and 545 * case is just a single output action, so that doing a clone and
@@ -562,12 +594,9 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
562 } 594 }
563 } 595 }
564 596
565 if (prev_port != -1) { 597 if (prev_port != -1)
566 if (keep_skb)
567 skb = skb_clone(skb, GFP_ATOMIC);
568
569 do_output(dp, skb, prev_port); 598 do_output(dp, skb, prev_port);
570 } else if (!keep_skb) 599 else
571 consume_skb(skb); 600 consume_skb(skb);
572 601
573 return 0; 602 return 0;
@@ -579,6 +608,5 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb)
579 struct sw_flow_actions *acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts); 608 struct sw_flow_actions *acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts);
580 609
581 OVS_CB(skb)->tun_key = NULL; 610 OVS_CB(skb)->tun_key = NULL;
582 return do_execute_actions(dp, skb, acts->actions, 611 return do_execute_actions(dp, skb, acts->actions, acts->actions_len);
583 acts->actions_len, false);
584} 612}
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 9db4bf6740d1..7ad3f029baae 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -66,16 +66,16 @@ static struct genl_family dp_packet_genl_family;
66static struct genl_family dp_flow_genl_family; 66static struct genl_family dp_flow_genl_family;
67static struct genl_family dp_datapath_genl_family; 67static struct genl_family dp_datapath_genl_family;
68 68
69static struct genl_multicast_group ovs_dp_flow_multicast_group = { 69static const struct genl_multicast_group ovs_dp_flow_multicast_group = {
70 .name = OVS_FLOW_MCGROUP 70 .name = OVS_FLOW_MCGROUP,
71}; 71};
72 72
73static struct genl_multicast_group ovs_dp_datapath_multicast_group = { 73static const struct genl_multicast_group ovs_dp_datapath_multicast_group = {
74 .name = OVS_DATAPATH_MCGROUP 74 .name = OVS_DATAPATH_MCGROUP,
75}; 75};
76 76
77struct genl_multicast_group ovs_dp_vport_multicast_group = { 77static const struct genl_multicast_group ovs_dp_vport_multicast_group = {
78 .name = OVS_VPORT_MCGROUP 78 .name = OVS_VPORT_MCGROUP,
79}; 79};
80 80
81/* Check if need to build a reply message. 81/* Check if need to build a reply message.
@@ -266,7 +266,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
266 upcall.cmd = OVS_PACKET_CMD_MISS; 266 upcall.cmd = OVS_PACKET_CMD_MISS;
267 upcall.key = &key; 267 upcall.key = &key;
268 upcall.userdata = NULL; 268 upcall.userdata = NULL;
269 upcall.portid = p->upcall_portid; 269 upcall.portid = ovs_vport_find_upcall_portid(p, skb);
270 ovs_dp_upcall(dp, skb, &upcall); 270 ovs_dp_upcall(dp, skb, &upcall);
271 consume_skb(skb); 271 consume_skb(skb);
272 stats_counter = &stats->n_missed; 272 stats_counter = &stats->n_missed;
@@ -464,7 +464,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
464 upcall->dp_ifindex = dp_ifindex; 464 upcall->dp_ifindex = dp_ifindex;
465 465
466 nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY); 466 nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY);
467 ovs_nla_put_flow(upcall_info->key, upcall_info->key, user_skb); 467 err = ovs_nla_put_flow(upcall_info->key, upcall_info->key, user_skb);
468 BUG_ON(err);
468 nla_nest_end(user_skb, nla); 469 nla_nest_end(user_skb, nla);
469 470
470 if (upcall_info->userdata) 471 if (upcall_info->userdata)
@@ -780,7 +781,7 @@ static struct sk_buff *ovs_flow_cmd_build_info(const struct sw_flow *flow,
780 781
781 skb = ovs_flow_cmd_alloc_info(ovsl_dereference(flow->sf_acts), info, 782 skb = ovs_flow_cmd_alloc_info(ovsl_dereference(flow->sf_acts), info,
782 always); 783 always);
783 if (!skb || IS_ERR(skb)) 784 if (IS_ERR_OR_NULL(skb))
784 return skb; 785 return skb;
785 786
786 retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb, 787 retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb,
@@ -1189,7 +1190,7 @@ static const struct nla_policy flow_policy[OVS_FLOW_ATTR_MAX + 1] = {
1189 [OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG }, 1190 [OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG },
1190}; 1191};
1191 1192
1192static struct genl_ops dp_flow_genl_ops[] = { 1193static const struct genl_ops dp_flow_genl_ops[] = {
1193 { .cmd = OVS_FLOW_CMD_NEW, 1194 { .cmd = OVS_FLOW_CMD_NEW,
1194 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ 1195 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1195 .policy = flow_policy, 1196 .policy = flow_policy,
@@ -1373,7 +1374,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
1373 parms.options = NULL; 1374 parms.options = NULL;
1374 parms.dp = dp; 1375 parms.dp = dp;
1375 parms.port_no = OVSP_LOCAL; 1376 parms.port_no = OVSP_LOCAL;
1376 parms.upcall_portid = nla_get_u32(a[OVS_DP_ATTR_UPCALL_PID]); 1377 parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID];
1377 1378
1378 ovs_dp_change(dp, a); 1379 ovs_dp_change(dp, a);
1379 1380
@@ -1577,7 +1578,7 @@ static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = {
1577 [OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 }, 1578 [OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 },
1578}; 1579};
1579 1580
1580static struct genl_ops dp_datapath_genl_ops[] = { 1581static const struct genl_ops dp_datapath_genl_ops[] = {
1581 { .cmd = OVS_DP_CMD_NEW, 1582 { .cmd = OVS_DP_CMD_NEW,
1582 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ 1583 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1583 .policy = datapath_policy, 1584 .policy = datapath_policy,
@@ -1632,8 +1633,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
1632 1633
1633 if (nla_put_u32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no) || 1634 if (nla_put_u32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no) ||
1634 nla_put_u32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type) || 1635 nla_put_u32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type) ||
1635 nla_put_string(skb, OVS_VPORT_ATTR_NAME, vport->ops->get_name(vport)) || 1636 nla_put_string(skb, OVS_VPORT_ATTR_NAME,
1636 nla_put_u32(skb, OVS_VPORT_ATTR_UPCALL_PID, vport->upcall_portid)) 1637 vport->ops->get_name(vport)))
1637 goto nla_put_failure; 1638 goto nla_put_failure;
1638 1639
1639 ovs_vport_get_stats(vport, &vport_stats); 1640 ovs_vport_get_stats(vport, &vport_stats);
@@ -1641,6 +1642,9 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
1641 &vport_stats)) 1642 &vport_stats))
1642 goto nla_put_failure; 1643 goto nla_put_failure;
1643 1644
1645 if (ovs_vport_get_upcall_portids(vport, skb))
1646 goto nla_put_failure;
1647
1644 err = ovs_vport_get_options(vport, skb); 1648 err = ovs_vport_get_options(vport, skb);
1645 if (err == -EMSGSIZE) 1649 if (err == -EMSGSIZE)
1646 goto error; 1650 goto error;
@@ -1762,7 +1766,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
1762 parms.options = a[OVS_VPORT_ATTR_OPTIONS]; 1766 parms.options = a[OVS_VPORT_ATTR_OPTIONS];
1763 parms.dp = dp; 1767 parms.dp = dp;
1764 parms.port_no = port_no; 1768 parms.port_no = port_no;
1765 parms.upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]); 1769 parms.upcall_portids = a[OVS_VPORT_ATTR_UPCALL_PID];
1766 1770
1767 vport = new_vport(&parms); 1771 vport = new_vport(&parms);
1768 err = PTR_ERR(vport); 1772 err = PTR_ERR(vport);
@@ -1812,8 +1816,14 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
1812 goto exit_unlock_free; 1816 goto exit_unlock_free;
1813 } 1817 }
1814 1818
1815 if (a[OVS_VPORT_ATTR_UPCALL_PID]) 1819
1816 vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]); 1820 if (a[OVS_VPORT_ATTR_UPCALL_PID]) {
1821 struct nlattr *ids = a[OVS_VPORT_ATTR_UPCALL_PID];
1822
1823 err = ovs_vport_set_upcall_portids(vport, ids);
1824 if (err)
1825 goto exit_unlock_free;
1826 }
1817 1827
1818 err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid, 1828 err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
1819 info->snd_seq, 0, OVS_VPORT_CMD_NEW); 1829 info->snd_seq, 0, OVS_VPORT_CMD_NEW);
@@ -1944,7 +1954,7 @@ static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = {
1944 [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED }, 1954 [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED },
1945}; 1955};
1946 1956
1947static struct genl_ops dp_vport_genl_ops[] = { 1957static const struct genl_ops dp_vport_genl_ops[] = {
1948 { .cmd = OVS_VPORT_CMD_NEW, 1958 { .cmd = OVS_VPORT_CMD_NEW,
1949 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ 1959 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1950 .policy = vport_policy, 1960 .policy = vport_policy,
@@ -2053,10 +2063,14 @@ static int __init dp_init(void)
2053 2063
2054 pr_info("Open vSwitch switching datapath\n"); 2064 pr_info("Open vSwitch switching datapath\n");
2055 2065
2056 err = ovs_flow_init(); 2066 err = ovs_internal_dev_rtnl_link_register();
2057 if (err) 2067 if (err)
2058 goto error; 2068 goto error;
2059 2069
2070 err = ovs_flow_init();
2071 if (err)
2072 goto error_unreg_rtnl_link;
2073
2060 err = ovs_vport_init(); 2074 err = ovs_vport_init();
2061 if (err) 2075 if (err)
2062 goto error_flow_exit; 2076 goto error_flow_exit;
@@ -2083,6 +2097,8 @@ error_vport_exit:
2083 ovs_vport_exit(); 2097 ovs_vport_exit();
2084error_flow_exit: 2098error_flow_exit:
2085 ovs_flow_exit(); 2099 ovs_flow_exit();
2100error_unreg_rtnl_link:
2101 ovs_internal_dev_rtnl_link_unregister();
2086error: 2102error:
2087 return err; 2103 return err;
2088} 2104}
@@ -2095,6 +2111,7 @@ static void dp_cleanup(void)
2095 rcu_barrier(); 2111 rcu_barrier();
2096 ovs_vport_exit(); 2112 ovs_vport_exit();
2097 ovs_flow_exit(); 2113 ovs_flow_exit();
2114 ovs_internal_dev_rtnl_link_unregister();
2098} 2115}
2099 2116
2100module_init(dp_init); 2117module_init(dp_init);
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h
index 7ede507500d7..701b5738c38a 100644
--- a/net/openvswitch/datapath.h
+++ b/net/openvswitch/datapath.h
@@ -144,7 +144,7 @@ int lockdep_ovsl_is_held(void);
144#define lockdep_ovsl_is_held() 1 144#define lockdep_ovsl_is_held() 1
145#endif 145#endif
146 146
147#define ASSERT_OVSL() WARN_ON(unlikely(!lockdep_ovsl_is_held())) 147#define ASSERT_OVSL() WARN_ON(!lockdep_ovsl_is_held())
148#define ovsl_dereference(p) \ 148#define ovsl_dereference(p) \
149 rcu_dereference_protected(p, lockdep_ovsl_is_held()) 149 rcu_dereference_protected(p, lockdep_ovsl_is_held())
150#define rcu_dereference_ovsl(p) \ 150#define rcu_dereference_ovsl(p) \
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index 789af9280e77..84516126e5f3 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -26,6 +26,7 @@
26 26
27#include <net/dst.h> 27#include <net/dst.h>
28#include <net/xfrm.h> 28#include <net/xfrm.h>
29#include <net/rtnetlink.h>
29 30
30#include "datapath.h" 31#include "datapath.h"
31#include "vport-internal_dev.h" 32#include "vport-internal_dev.h"
@@ -121,6 +122,10 @@ static const struct net_device_ops internal_dev_netdev_ops = {
121 .ndo_get_stats64 = internal_dev_get_stats, 122 .ndo_get_stats64 = internal_dev_get_stats,
122}; 123};
123 124
125static struct rtnl_link_ops internal_dev_link_ops __read_mostly = {
126 .kind = "openvswitch",
127};
128
124static void do_setup(struct net_device *netdev) 129static void do_setup(struct net_device *netdev)
125{ 130{
126 ether_setup(netdev); 131 ether_setup(netdev);
@@ -131,14 +136,18 @@ static void do_setup(struct net_device *netdev)
131 netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE; 136 netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
132 netdev->destructor = internal_dev_destructor; 137 netdev->destructor = internal_dev_destructor;
133 netdev->ethtool_ops = &internal_dev_ethtool_ops; 138 netdev->ethtool_ops = &internal_dev_ethtool_ops;
139 netdev->rtnl_link_ops = &internal_dev_link_ops;
134 netdev->tx_queue_len = 0; 140 netdev->tx_queue_len = 0;
135 141
136 netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST | 142 netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST |
137 NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE; 143 NETIF_F_HIGHDMA | NETIF_F_HW_CSUM |
144 NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL;
138 145
139 netdev->vlan_features = netdev->features; 146 netdev->vlan_features = netdev->features;
147 netdev->hw_enc_features = netdev->features;
140 netdev->features |= NETIF_F_HW_VLAN_CTAG_TX; 148 netdev->features |= NETIF_F_HW_VLAN_CTAG_TX;
141 netdev->hw_features = netdev->features & ~NETIF_F_LLTX; 149 netdev->hw_features = netdev->features & ~NETIF_F_LLTX;
150
142 eth_hw_addr_random(netdev); 151 eth_hw_addr_random(netdev);
143} 152}
144 153
@@ -159,7 +168,8 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
159 netdev_vport = netdev_vport_priv(vport); 168 netdev_vport = netdev_vport_priv(vport);
160 169
161 netdev_vport->dev = alloc_netdev(sizeof(struct internal_dev), 170 netdev_vport->dev = alloc_netdev(sizeof(struct internal_dev),
162 parms->name, do_setup); 171 parms->name, NET_NAME_UNKNOWN,
172 do_setup);
163 if (!netdev_vport->dev) { 173 if (!netdev_vport->dev) {
164 err = -ENOMEM; 174 err = -ENOMEM;
165 goto error_free_vport; 175 goto error_free_vport;
@@ -248,3 +258,13 @@ struct vport *ovs_internal_dev_get_vport(struct net_device *netdev)
248 258
249 return internal_dev_priv(netdev)->vport; 259 return internal_dev_priv(netdev)->vport;
250} 260}
261
262int ovs_internal_dev_rtnl_link_register(void)
263{
264 return rtnl_link_register(&internal_dev_link_ops);
265}
266
267void ovs_internal_dev_rtnl_link_unregister(void)
268{
269 rtnl_link_unregister(&internal_dev_link_ops);
270}
diff --git a/net/openvswitch/vport-internal_dev.h b/net/openvswitch/vport-internal_dev.h
index 9a7d30ecc6a2..1b179a190cff 100644
--- a/net/openvswitch/vport-internal_dev.h
+++ b/net/openvswitch/vport-internal_dev.h
@@ -24,5 +24,7 @@
24 24
25int ovs_is_internal_dev(const struct net_device *); 25int ovs_is_internal_dev(const struct net_device *);
26struct vport *ovs_internal_dev_get_vport(struct net_device *); 26struct vport *ovs_internal_dev_get_vport(struct net_device *);
27int ovs_internal_dev_rtnl_link_register(void);
28void ovs_internal_dev_rtnl_link_unregister(void);
27 29
28#endif /* vport-internal_dev.h */ 30#endif /* vport-internal_dev.h */
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
index 0edbd95c60e7..d8b7e247bebf 100644
--- a/net/openvswitch/vport-vxlan.c
+++ b/net/openvswitch/vport-vxlan.c
@@ -143,8 +143,6 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
143 struct rtable *rt; 143 struct rtable *rt;
144 struct flowi4 fl; 144 struct flowi4 fl;
145 __be16 src_port; 145 __be16 src_port;
146 int port_min;
147 int port_max;
148 __be16 df; 146 __be16 df;
149 int err; 147 int err;
150 148
@@ -172,8 +170,7 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
172 170
173 skb->ignore_df = 1; 171 skb->ignore_df = 1;
174 172
175 inet_get_local_port_range(net, &port_min, &port_max); 173 src_port = udp_flow_src_port(net, skb, 0, 0, true);
176 src_port = vxlan_src_port(port_min, port_max, skb);
177 174
178 err = vxlan_xmit_skb(vxlan_port->vs, rt, skb, 175 err = vxlan_xmit_skb(vxlan_port->vs, rt, skb,
179 fl.saddr, OVS_CB(skb)->tun_key->ipv4_dst, 176 fl.saddr, OVS_CB(skb)->tun_key->ipv4_dst,
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index 42c0f4a0b78c..702fb21bfe15 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -134,10 +134,12 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,
134 134
135 vport->dp = parms->dp; 135 vport->dp = parms->dp;
136 vport->port_no = parms->port_no; 136 vport->port_no = parms->port_no;
137 vport->upcall_portid = parms->upcall_portid;
138 vport->ops = ops; 137 vport->ops = ops;
139 INIT_HLIST_NODE(&vport->dp_hash_node); 138 INIT_HLIST_NODE(&vport->dp_hash_node);
140 139
140 if (ovs_vport_set_upcall_portids(vport, parms->upcall_portids))
141 return ERR_PTR(-EINVAL);
142
141 vport->percpu_stats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); 143 vport->percpu_stats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
142 if (!vport->percpu_stats) { 144 if (!vport->percpu_stats) {
143 kfree(vport); 145 kfree(vport);
@@ -161,6 +163,10 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,
161 */ 163 */
162void ovs_vport_free(struct vport *vport) 164void ovs_vport_free(struct vport *vport)
163{ 165{
166 /* vport is freed from RCU callback or error path, Therefore
167 * it is safe to use raw dereference.
168 */
169 kfree(rcu_dereference_raw(vport->upcall_portids));
164 free_percpu(vport->percpu_stats); 170 free_percpu(vport->percpu_stats);
165 kfree(vport); 171 kfree(vport);
166} 172}
@@ -327,6 +333,99 @@ int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb)
327} 333}
328 334
329/** 335/**
336 * ovs_vport_set_upcall_portids - set upcall portids of @vport.
337 *
338 * @vport: vport to modify.
339 * @ids: new configuration, an array of port ids.
340 *
341 * Sets the vport's upcall_portids to @ids.
342 *
343 * Returns 0 if successful, -EINVAL if @ids is zero length or cannot be parsed
344 * as an array of U32.
345 *
346 * Must be called with ovs_mutex.
347 */
348int ovs_vport_set_upcall_portids(struct vport *vport, struct nlattr *ids)
349{
350 struct vport_portids *old, *vport_portids;
351
352 if (!nla_len(ids) || nla_len(ids) % sizeof(u32))
353 return -EINVAL;
354
355 old = ovsl_dereference(vport->upcall_portids);
356
357 vport_portids = kmalloc(sizeof(*vport_portids) + nla_len(ids),
358 GFP_KERNEL);
359 if (!vport_portids)
360 return -ENOMEM;
361
362 vport_portids->n_ids = nla_len(ids) / sizeof(u32);
363 vport_portids->rn_ids = reciprocal_value(vport_portids->n_ids);
364 nla_memcpy(vport_portids->ids, ids, nla_len(ids));
365
366 rcu_assign_pointer(vport->upcall_portids, vport_portids);
367
368 if (old)
369 kfree_rcu(old, rcu);
370 return 0;
371}
372
373/**
374 * ovs_vport_get_upcall_portids - get the upcall_portids of @vport.
375 *
376 * @vport: vport from which to retrieve the portids.
377 * @skb: sk_buff where portids should be appended.
378 *
379 * Retrieves the configuration of the given vport, appending the
380 * %OVS_VPORT_ATTR_UPCALL_PID attribute which is the array of upcall
381 * portids to @skb.
382 *
383 * Returns 0 if successful, -EMSGSIZE if @skb has insufficient room.
384 * If an error occurs, @skb is left unmodified. Must be called with
385 * ovs_mutex or rcu_read_lock.
386 */
387int ovs_vport_get_upcall_portids(const struct vport *vport,
388 struct sk_buff *skb)
389{
390 struct vport_portids *ids;
391
392 ids = rcu_dereference_ovsl(vport->upcall_portids);
393
394 if (vport->dp->user_features & OVS_DP_F_VPORT_PIDS)
395 return nla_put(skb, OVS_VPORT_ATTR_UPCALL_PID,
396 ids->n_ids * sizeof(u32), (void *)ids->ids);
397 else
398 return nla_put_u32(skb, OVS_VPORT_ATTR_UPCALL_PID, ids->ids[0]);
399}
400
401/**
402 * ovs_vport_find_upcall_portid - find the upcall portid to send upcall.
403 *
404 * @vport: vport from which the missed packet is received.
405 * @skb: skb that the missed packet was received.
406 *
407 * Uses the skb_get_hash() to select the upcall portid to send the
408 * upcall.
409 *
410 * Returns the portid of the target socket. Must be called with rcu_read_lock.
411 */
412u32 ovs_vport_find_upcall_portid(const struct vport *p, struct sk_buff *skb)
413{
414 struct vport_portids *ids;
415 u32 ids_index;
416 u32 hash;
417
418 ids = rcu_dereference(p->upcall_portids);
419
420 if (ids->n_ids == 1 && ids->ids[0] == 0)
421 return 0;
422
423 hash = skb_get_hash(skb);
424 ids_index = hash - ids->n_ids * reciprocal_divide(hash, ids->rn_ids);
425 return ids->ids[ids_index];
426}
427
428/**
330 * ovs_vport_receive - pass up received packet to the datapath for processing 429 * ovs_vport_receive - pass up received packet to the datapath for processing
331 * 430 *
332 * @vport: vport that received the packet 431 * @vport: vport that received the packet
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h
index 8d721e62f388..35f89d84b45e 100644
--- a/net/openvswitch/vport.h
+++ b/net/openvswitch/vport.h
@@ -23,6 +23,7 @@
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/netlink.h> 24#include <linux/netlink.h>
25#include <linux/openvswitch.h> 25#include <linux/openvswitch.h>
26#include <linux/reciprocal_div.h>
26#include <linux/skbuff.h> 27#include <linux/skbuff.h>
27#include <linux/spinlock.h> 28#include <linux/spinlock.h>
28#include <linux/u64_stats_sync.h> 29#include <linux/u64_stats_sync.h>
@@ -52,6 +53,10 @@ void ovs_vport_get_stats(struct vport *, struct ovs_vport_stats *);
52int ovs_vport_set_options(struct vport *, struct nlattr *options); 53int ovs_vport_set_options(struct vport *, struct nlattr *options);
53int ovs_vport_get_options(const struct vport *, struct sk_buff *); 54int ovs_vport_get_options(const struct vport *, struct sk_buff *);
54 55
56int ovs_vport_set_upcall_portids(struct vport *, struct nlattr *pids);
57int ovs_vport_get_upcall_portids(const struct vport *, struct sk_buff *);
58u32 ovs_vport_find_upcall_portid(const struct vport *, struct sk_buff *);
59
55int ovs_vport_send(struct vport *, struct sk_buff *); 60int ovs_vport_send(struct vport *, struct sk_buff *);
56 61
57/* The following definitions are for implementers of vport devices: */ 62/* The following definitions are for implementers of vport devices: */
@@ -62,13 +67,27 @@ struct vport_err_stats {
62 u64 tx_dropped; 67 u64 tx_dropped;
63 u64 tx_errors; 68 u64 tx_errors;
64}; 69};
70/**
71 * struct vport_portids - array of netlink portids of a vport.
72 * must be protected by rcu.
73 * @rn_ids: The reciprocal value of @n_ids.
74 * @rcu: RCU callback head for deferred destruction.
75 * @n_ids: Size of @ids array.
76 * @ids: Array storing the Netlink socket pids to be used for packets received
77 * on this port that miss the flow table.
78 */
79struct vport_portids {
80 struct reciprocal_value rn_ids;
81 struct rcu_head rcu;
82 u32 n_ids;
83 u32 ids[];
84};
65 85
66/** 86/**
67 * struct vport - one port within a datapath 87 * struct vport - one port within a datapath
68 * @rcu: RCU callback head for deferred destruction. 88 * @rcu: RCU callback head for deferred destruction.
69 * @dp: Datapath to which this port belongs. 89 * @dp: Datapath to which this port belongs.
70 * @upcall_portid: The Netlink port to use for packets received on this port that 90 * @upcall_portids: RCU protected 'struct vport_portids'.
71 * miss the flow table.
72 * @port_no: Index into @dp's @ports array. 91 * @port_no: Index into @dp's @ports array.
73 * @hash_node: Element in @dev_table hash table in vport.c. 92 * @hash_node: Element in @dev_table hash table in vport.c.
74 * @dp_hash_node: Element in @datapath->ports hash table in datapath.c. 93 * @dp_hash_node: Element in @datapath->ports hash table in datapath.c.
@@ -80,7 +99,7 @@ struct vport_err_stats {
80struct vport { 99struct vport {
81 struct rcu_head rcu; 100 struct rcu_head rcu;
82 struct datapath *dp; 101 struct datapath *dp;
83 u32 upcall_portid; 102 struct vport_portids __rcu *upcall_portids;
84 u16 port_no; 103 u16 port_no;
85 104
86 struct hlist_node hash_node; 105 struct hlist_node hash_node;
@@ -111,7 +130,7 @@ struct vport_parms {
111 /* For ovs_vport_alloc(). */ 130 /* For ovs_vport_alloc(). */
112 struct datapath *dp; 131 struct datapath *dp;
113 u16 port_no; 132 u16 port_no;
114 u32 upcall_portid; 133 struct nlattr *upcall_portids;
115}; 134};
116 135
117/** 136/**