aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r--net/openvswitch/datapath.c57
1 files changed, 36 insertions, 21 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 9db4bf6740d1..7228ec3faf19 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -47,8 +47,6 @@
47#include <linux/openvswitch.h> 47#include <linux/openvswitch.h>
48#include <linux/rculist.h> 48#include <linux/rculist.h>
49#include <linux/dmi.h> 49#include <linux/dmi.h>
50#include <linux/genetlink.h>
51#include <net/genetlink.h>
52#include <net/genetlink.h> 50#include <net/genetlink.h>
53#include <net/net_namespace.h> 51#include <net/net_namespace.h>
54#include <net/netns/generic.h> 52#include <net/netns/generic.h>
@@ -66,16 +64,16 @@ static struct genl_family dp_packet_genl_family;
66static struct genl_family dp_flow_genl_family; 64static struct genl_family dp_flow_genl_family;
67static struct genl_family dp_datapath_genl_family; 65static struct genl_family dp_datapath_genl_family;
68 66
69static struct genl_multicast_group ovs_dp_flow_multicast_group = { 67static const struct genl_multicast_group ovs_dp_flow_multicast_group = {
70 .name = OVS_FLOW_MCGROUP 68 .name = OVS_FLOW_MCGROUP,
71}; 69};
72 70
73static struct genl_multicast_group ovs_dp_datapath_multicast_group = { 71static const struct genl_multicast_group ovs_dp_datapath_multicast_group = {
74 .name = OVS_DATAPATH_MCGROUP 72 .name = OVS_DATAPATH_MCGROUP,
75}; 73};
76 74
77struct genl_multicast_group ovs_dp_vport_multicast_group = { 75static const struct genl_multicast_group ovs_dp_vport_multicast_group = {
78 .name = OVS_VPORT_MCGROUP 76 .name = OVS_VPORT_MCGROUP,
79}; 77};
80 78
81/* Check if need to build a reply message. 79/* Check if need to build a reply message.
@@ -266,7 +264,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
266 upcall.cmd = OVS_PACKET_CMD_MISS; 264 upcall.cmd = OVS_PACKET_CMD_MISS;
267 upcall.key = &key; 265 upcall.key = &key;
268 upcall.userdata = NULL; 266 upcall.userdata = NULL;
269 upcall.portid = p->upcall_portid; 267 upcall.portid = ovs_vport_find_upcall_portid(p, skb);
270 ovs_dp_upcall(dp, skb, &upcall); 268 ovs_dp_upcall(dp, skb, &upcall);
271 consume_skb(skb); 269 consume_skb(skb);
272 stats_counter = &stats->n_missed; 270 stats_counter = &stats->n_missed;
@@ -464,7 +462,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
464 upcall->dp_ifindex = dp_ifindex; 462 upcall->dp_ifindex = dp_ifindex;
465 463
466 nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY); 464 nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY);
467 ovs_nla_put_flow(upcall_info->key, upcall_info->key, user_skb); 465 err = ovs_nla_put_flow(upcall_info->key, upcall_info->key, user_skb);
466 BUG_ON(err);
468 nla_nest_end(user_skb, nla); 467 nla_nest_end(user_skb, nla);
469 468
470 if (upcall_info->userdata) 469 if (upcall_info->userdata)
@@ -780,7 +779,7 @@ static struct sk_buff *ovs_flow_cmd_build_info(const struct sw_flow *flow,
780 779
781 skb = ovs_flow_cmd_alloc_info(ovsl_dereference(flow->sf_acts), info, 780 skb = ovs_flow_cmd_alloc_info(ovsl_dereference(flow->sf_acts), info,
782 always); 781 always);
783 if (!skb || IS_ERR(skb)) 782 if (IS_ERR_OR_NULL(skb))
784 return skb; 783 return skb;
785 784
786 retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb, 785 retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb,
@@ -1189,7 +1188,7 @@ static const struct nla_policy flow_policy[OVS_FLOW_ATTR_MAX + 1] = {
1189 [OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG }, 1188 [OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG },
1190}; 1189};
1191 1190
1192static struct genl_ops dp_flow_genl_ops[] = { 1191static const struct genl_ops dp_flow_genl_ops[] = {
1193 { .cmd = OVS_FLOW_CMD_NEW, 1192 { .cmd = OVS_FLOW_CMD_NEW,
1194 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ 1193 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1195 .policy = flow_policy, 1194 .policy = flow_policy,
@@ -1373,7 +1372,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
1373 parms.options = NULL; 1372 parms.options = NULL;
1374 parms.dp = dp; 1373 parms.dp = dp;
1375 parms.port_no = OVSP_LOCAL; 1374 parms.port_no = OVSP_LOCAL;
1376 parms.upcall_portid = nla_get_u32(a[OVS_DP_ATTR_UPCALL_PID]); 1375 parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID];
1377 1376
1378 ovs_dp_change(dp, a); 1377 ovs_dp_change(dp, a);
1379 1378
@@ -1577,7 +1576,7 @@ static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = {
1577 [OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 }, 1576 [OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 },
1578}; 1577};
1579 1578
1580static struct genl_ops dp_datapath_genl_ops[] = { 1579static const struct genl_ops dp_datapath_genl_ops[] = {
1581 { .cmd = OVS_DP_CMD_NEW, 1580 { .cmd = OVS_DP_CMD_NEW,
1582 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ 1581 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1583 .policy = datapath_policy, 1582 .policy = datapath_policy,
@@ -1632,8 +1631,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
1632 1631
1633 if (nla_put_u32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no) || 1632 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) || 1633 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)) || 1634 nla_put_string(skb, OVS_VPORT_ATTR_NAME,
1636 nla_put_u32(skb, OVS_VPORT_ATTR_UPCALL_PID, vport->upcall_portid)) 1635 vport->ops->get_name(vport)))
1637 goto nla_put_failure; 1636 goto nla_put_failure;
1638 1637
1639 ovs_vport_get_stats(vport, &vport_stats); 1638 ovs_vport_get_stats(vport, &vport_stats);
@@ -1641,6 +1640,9 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
1641 &vport_stats)) 1640 &vport_stats))
1642 goto nla_put_failure; 1641 goto nla_put_failure;
1643 1642
1643 if (ovs_vport_get_upcall_portids(vport, skb))
1644 goto nla_put_failure;
1645
1644 err = ovs_vport_get_options(vport, skb); 1646 err = ovs_vport_get_options(vport, skb);
1645 if (err == -EMSGSIZE) 1647 if (err == -EMSGSIZE)
1646 goto error; 1648 goto error;
@@ -1762,7 +1764,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
1762 parms.options = a[OVS_VPORT_ATTR_OPTIONS]; 1764 parms.options = a[OVS_VPORT_ATTR_OPTIONS];
1763 parms.dp = dp; 1765 parms.dp = dp;
1764 parms.port_no = port_no; 1766 parms.port_no = port_no;
1765 parms.upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]); 1767 parms.upcall_portids = a[OVS_VPORT_ATTR_UPCALL_PID];
1766 1768
1767 vport = new_vport(&parms); 1769 vport = new_vport(&parms);
1768 err = PTR_ERR(vport); 1770 err = PTR_ERR(vport);
@@ -1812,8 +1814,14 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
1812 goto exit_unlock_free; 1814 goto exit_unlock_free;
1813 } 1815 }
1814 1816
1815 if (a[OVS_VPORT_ATTR_UPCALL_PID]) 1817
1816 vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]); 1818 if (a[OVS_VPORT_ATTR_UPCALL_PID]) {
1819 struct nlattr *ids = a[OVS_VPORT_ATTR_UPCALL_PID];
1820
1821 err = ovs_vport_set_upcall_portids(vport, ids);
1822 if (err)
1823 goto exit_unlock_free;
1824 }
1817 1825
1818 err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid, 1826 err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
1819 info->snd_seq, 0, OVS_VPORT_CMD_NEW); 1827 info->snd_seq, 0, OVS_VPORT_CMD_NEW);
@@ -1944,7 +1952,7 @@ static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = {
1944 [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED }, 1952 [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED },
1945}; 1953};
1946 1954
1947static struct genl_ops dp_vport_genl_ops[] = { 1955static const struct genl_ops dp_vport_genl_ops[] = {
1948 { .cmd = OVS_VPORT_CMD_NEW, 1956 { .cmd = OVS_VPORT_CMD_NEW,
1949 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ 1957 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1950 .policy = vport_policy, 1958 .policy = vport_policy,
@@ -2053,10 +2061,14 @@ static int __init dp_init(void)
2053 2061
2054 pr_info("Open vSwitch switching datapath\n"); 2062 pr_info("Open vSwitch switching datapath\n");
2055 2063
2056 err = ovs_flow_init(); 2064 err = ovs_internal_dev_rtnl_link_register();
2057 if (err) 2065 if (err)
2058 goto error; 2066 goto error;
2059 2067
2068 err = ovs_flow_init();
2069 if (err)
2070 goto error_unreg_rtnl_link;
2071
2060 err = ovs_vport_init(); 2072 err = ovs_vport_init();
2061 if (err) 2073 if (err)
2062 goto error_flow_exit; 2074 goto error_flow_exit;
@@ -2083,6 +2095,8 @@ error_vport_exit:
2083 ovs_vport_exit(); 2095 ovs_vport_exit();
2084error_flow_exit: 2096error_flow_exit:
2085 ovs_flow_exit(); 2097 ovs_flow_exit();
2098error_unreg_rtnl_link:
2099 ovs_internal_dev_rtnl_link_unregister();
2086error: 2100error:
2087 return err; 2101 return err;
2088} 2102}
@@ -2095,6 +2109,7 @@ static void dp_cleanup(void)
2095 rcu_barrier(); 2109 rcu_barrier();
2096 ovs_vport_exit(); 2110 ovs_vport_exit();
2097 ovs_flow_exit(); 2111 ovs_flow_exit();
2112 ovs_internal_dev_rtnl_link_unregister();
2098} 2113}
2099 2114
2100module_init(dp_init); 2115module_init(dp_init);