aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJesse Gross <jesse@nicira.com>2014-10-03 18:35:31 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-06 00:32:20 -0400
commitf0b128c1e2cc33ad104daf0f51a51e34f7763c5f (patch)
tree41b08ab786ae83f1890cafb6847d1fd67884af5f /net
parent67fa034194bf82a3d5ca841759d921297daa63ca (diff)
openvswitch: Wrap struct ovs_key_ipv4_tunnel in a new structure.
Currently, the flow information that is matched for tunnels and the tunnel data passed around with packets is the same. However, as additional information is added this is not necessarily desirable, as in the case of pointers. This adds a new structure for tunnel metadata which currently contains only the existing struct. This change is purely internal to the kernel since the current OVS_KEY_ATTR_IPV4_TUNNEL is simply a compressed version of OVS_KEY_ATTR_TUNNEL that is translated at flow setup. Signed-off-by: Jesse Gross <jesse@nicira.com> Signed-off-by: Andy Zhou <azhou@nicira.com> Acked-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/openvswitch/actions.c5
-rw-r--r--net/openvswitch/datapath.h2
-rw-r--r--net/openvswitch/flow.c6
-rw-r--r--net/openvswitch/flow.h30
-rw-r--r--net/openvswitch/flow_netlink.c38
-rw-r--r--net/openvswitch/vport-gre.c16
-rw-r--r--net/openvswitch/vport-vxlan.c10
-rw-r--r--net/openvswitch/vport.c6
-rw-r--r--net/openvswitch/vport.h2
9 files changed, 73 insertions, 42 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 6932a42e41a2..006886dbee36 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -590,8 +590,8 @@ static int execute_set_action(struct sk_buff *skb,
590 skb->mark = nla_get_u32(nested_attr); 590 skb->mark = nla_get_u32(nested_attr);
591 break; 591 break;
592 592
593 case OVS_KEY_ATTR_IPV4_TUNNEL: 593 case OVS_KEY_ATTR_TUNNEL_INFO:
594 OVS_CB(skb)->egress_tun_key = nla_data(nested_attr); 594 OVS_CB(skb)->egress_tun_info = nla_data(nested_attr);
595 break; 595 break;
596 596
597 case OVS_KEY_ATTR_ETHERNET: 597 case OVS_KEY_ATTR_ETHERNET:
@@ -778,6 +778,7 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
778 acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts); 778 acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts);
779 779
780 this_cpu_inc(exec_actions_level); 780 this_cpu_inc(exec_actions_level);
781 OVS_CB(skb)->egress_tun_info = NULL;
781 err = do_execute_actions(dp, skb, key, 782 err = do_execute_actions(dp, skb, key,
782 acts->actions, acts->actions_len); 783 acts->actions, acts->actions_len);
783 784
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h
index ac3f3df96961..974135439c5c 100644
--- a/net/openvswitch/datapath.h
+++ b/net/openvswitch/datapath.h
@@ -102,8 +102,8 @@ struct datapath {
102 */ 102 */
103struct ovs_skb_cb { 103struct ovs_skb_cb {
104 struct sw_flow *flow; 104 struct sw_flow *flow;
105 struct ovs_tunnel_info *egress_tun_info;
105 struct vport *input_vport; 106 struct vport *input_vport;
106 struct ovs_key_ipv4_tunnel *egress_tun_key;
107}; 107};
108#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb) 108#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
109 109
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 913bdc1a83c0..2924cb340868 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -642,12 +642,12 @@ int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key)
642 return key_extract(skb, key); 642 return key_extract(skb, key);
643} 643}
644 644
645int ovs_flow_key_extract(struct ovs_key_ipv4_tunnel *tun_key, 645int ovs_flow_key_extract(struct ovs_tunnel_info *tun_info,
646 struct sk_buff *skb, struct sw_flow_key *key) 646 struct sk_buff *skb, struct sw_flow_key *key)
647{ 647{
648 /* Extract metadata from packet. */ 648 /* Extract metadata from packet. */
649 if (tun_key) 649 if (tun_info)
650 memcpy(&key->tun_key, tun_key, sizeof(key->tun_key)); 650 memcpy(&key->tun_key, &tun_info->tunnel, sizeof(key->tun_key));
651 else 651 else
652 memset(&key->tun_key, 0, sizeof(key->tun_key)); 652 memset(&key->tun_key, 0, sizeof(key->tun_key));
653 653
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 0f5db4ec565d..fe5a71b81c1f 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -49,20 +49,24 @@ struct ovs_key_ipv4_tunnel {
49 u8 ipv4_ttl; 49 u8 ipv4_ttl;
50} __packed __aligned(4); /* Minimize padding. */ 50} __packed __aligned(4); /* Minimize padding. */
51 51
52static inline void ovs_flow_tun_key_init(struct ovs_key_ipv4_tunnel *tun_key, 52struct ovs_tunnel_info {
53 const struct iphdr *iph, __be64 tun_id, 53 struct ovs_key_ipv4_tunnel tunnel;
54 __be16 tun_flags) 54};
55
56static inline void ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info,
57 const struct iphdr *iph,
58 __be64 tun_id, __be16 tun_flags)
55{ 59{
56 tun_key->tun_id = tun_id; 60 tun_info->tunnel.tun_id = tun_id;
57 tun_key->ipv4_src = iph->saddr; 61 tun_info->tunnel.ipv4_src = iph->saddr;
58 tun_key->ipv4_dst = iph->daddr; 62 tun_info->tunnel.ipv4_dst = iph->daddr;
59 tun_key->ipv4_tos = iph->tos; 63 tun_info->tunnel.ipv4_tos = iph->tos;
60 tun_key->ipv4_ttl = iph->ttl; 64 tun_info->tunnel.ipv4_ttl = iph->ttl;
61 tun_key->tun_flags = tun_flags; 65 tun_info->tunnel.tun_flags = tun_flags;
62 66
63 /* clear struct padding. */ 67 /* clear struct padding. */
64 memset((unsigned char *) tun_key + OVS_TUNNEL_KEY_SIZE, 0, 68 memset((unsigned char *)&tun_info->tunnel + OVS_TUNNEL_KEY_SIZE, 0,
65 sizeof(*tun_key) - OVS_TUNNEL_KEY_SIZE); 69 sizeof(tun_info->tunnel) - OVS_TUNNEL_KEY_SIZE);
66} 70}
67 71
68struct sw_flow_key { 72struct sw_flow_key {
@@ -190,8 +194,8 @@ void ovs_flow_stats_clear(struct sw_flow *);
190u64 ovs_flow_used_time(unsigned long flow_jiffies); 194u64 ovs_flow_used_time(unsigned long flow_jiffies);
191 195
192int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key); 196int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key);
193int ovs_flow_key_extract(struct ovs_key_ipv4_tunnel *tun_key, 197int ovs_flow_key_extract(struct ovs_tunnel_info *tun_info, struct sk_buff *skb,
194 struct sk_buff *skb, struct sw_flow_key *key); 198 struct sw_flow_key *key);
195/* Extract key from packet coming from userspace. */ 199/* Extract key from packet coming from userspace. */
196int ovs_flow_key_extract_userspace(const struct nlattr *attr, 200int ovs_flow_key_extract_userspace(const struct nlattr *attr,
197 struct sk_buff *skb, 201 struct sk_buff *skb,
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 22c855fa0bc2..5d6194d9dadc 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -1148,13 +1148,14 @@ out:
1148 return (struct nlattr *) ((unsigned char *)(*sfa) + next_offset); 1148 return (struct nlattr *) ((unsigned char *)(*sfa) + next_offset);
1149} 1149}
1150 1150
1151static int add_action(struct sw_flow_actions **sfa, int attrtype, void *data, int len) 1151static struct nlattr *__add_action(struct sw_flow_actions **sfa,
1152 int attrtype, void *data, int len)
1152{ 1153{
1153 struct nlattr *a; 1154 struct nlattr *a;
1154 1155
1155 a = reserve_sfa_size(sfa, nla_attr_size(len)); 1156 a = reserve_sfa_size(sfa, nla_attr_size(len));
1156 if (IS_ERR(a)) 1157 if (IS_ERR(a))
1157 return PTR_ERR(a); 1158 return a;
1158 1159
1159 a->nla_type = attrtype; 1160 a->nla_type = attrtype;
1160 a->nla_len = nla_attr_size(len); 1161 a->nla_len = nla_attr_size(len);
@@ -1163,6 +1164,18 @@ static int add_action(struct sw_flow_actions **sfa, int attrtype, void *data, in
1163 memcpy(nla_data(a), data, len); 1164 memcpy(nla_data(a), data, len);
1164 memset((unsigned char *) a + a->nla_len, 0, nla_padlen(len)); 1165 memset((unsigned char *) a + a->nla_len, 0, nla_padlen(len));
1165 1166
1167 return a;
1168}
1169
1170static int add_action(struct sw_flow_actions **sfa, int attrtype,
1171 void *data, int len)
1172{
1173 struct nlattr *a;
1174
1175 a = __add_action(sfa, attrtype, data, len);
1176 if (IS_ERR(a))
1177 return PTR_ERR(a);
1178
1166 return 0; 1179 return 0;
1167} 1180}
1168 1181
@@ -1268,6 +1281,8 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
1268{ 1281{
1269 struct sw_flow_match match; 1282 struct sw_flow_match match;
1270 struct sw_flow_key key; 1283 struct sw_flow_key key;
1284 struct ovs_tunnel_info *tun_info;
1285 struct nlattr *a;
1271 int err, start; 1286 int err, start;
1272 1287
1273 ovs_match_init(&match, &key, NULL); 1288 ovs_match_init(&match, &key, NULL);
@@ -1279,8 +1294,14 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
1279 if (start < 0) 1294 if (start < 0)
1280 return start; 1295 return start;
1281 1296
1282 err = add_action(sfa, OVS_KEY_ATTR_IPV4_TUNNEL, &match.key->tun_key, 1297 a = __add_action(sfa, OVS_KEY_ATTR_TUNNEL_INFO, NULL,
1283 sizeof(match.key->tun_key)); 1298 sizeof(*tun_info));
1299 if (IS_ERR(a))
1300 return PTR_ERR(a);
1301
1302 tun_info = nla_data(a);
1303 tun_info->tunnel = key.tun_key;
1304
1284 add_nested_action_end(*sfa, start); 1305 add_nested_action_end(*sfa, start);
1285 1306
1286 return err; 1307 return err;
@@ -1563,17 +1584,20 @@ static int set_action_to_attr(const struct nlattr *a, struct sk_buff *skb)
1563 int err; 1584 int err;
1564 1585
1565 switch (key_type) { 1586 switch (key_type) {
1566 case OVS_KEY_ATTR_IPV4_TUNNEL: 1587 case OVS_KEY_ATTR_TUNNEL_INFO: {
1588 struct ovs_tunnel_info *tun_info = nla_data(ovs_key);
1589
1567 start = nla_nest_start(skb, OVS_ACTION_ATTR_SET); 1590 start = nla_nest_start(skb, OVS_ACTION_ATTR_SET);
1568 if (!start) 1591 if (!start)
1569 return -EMSGSIZE; 1592 return -EMSGSIZE;
1570 1593
1571 err = ipv4_tun_to_nlattr(skb, nla_data(ovs_key), 1594 err = ipv4_tun_to_nlattr(skb, &tun_info->tunnel,
1572 nla_data(ovs_key)); 1595 nla_data(ovs_key));
1573 if (err) 1596 if (err)
1574 return err; 1597 return err;
1575 nla_nest_end(skb, start); 1598 nla_nest_end(skb, start);
1576 break; 1599 break;
1600 }
1577 default: 1601 default:
1578 if (nla_put(skb, OVS_ACTION_ATTR_SET, nla_len(a), ovs_key)) 1602 if (nla_put(skb, OVS_ACTION_ATTR_SET, nla_len(a), ovs_key))
1579 return -EMSGSIZE; 1603 return -EMSGSIZE;
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
index 309cca6e816f..fe768bd600eb 100644
--- a/net/openvswitch/vport-gre.c
+++ b/net/openvswitch/vport-gre.c
@@ -63,8 +63,10 @@ static __be16 filter_tnl_flags(__be16 flags)
63static struct sk_buff *__build_header(struct sk_buff *skb, 63static struct sk_buff *__build_header(struct sk_buff *skb,
64 int tunnel_hlen) 64 int tunnel_hlen)
65{ 65{
66 const struct ovs_key_ipv4_tunnel *tun_key = OVS_CB(skb)->egress_tun_key;
67 struct tnl_ptk_info tpi; 66 struct tnl_ptk_info tpi;
67 const struct ovs_key_ipv4_tunnel *tun_key;
68
69 tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
68 70
69 skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM)); 71 skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM));
70 if (IS_ERR(skb)) 72 if (IS_ERR(skb))
@@ -92,7 +94,7 @@ static __be64 key_to_tunnel_id(__be32 key, __be32 seq)
92static int gre_rcv(struct sk_buff *skb, 94static int gre_rcv(struct sk_buff *skb,
93 const struct tnl_ptk_info *tpi) 95 const struct tnl_ptk_info *tpi)
94{ 96{
95 struct ovs_key_ipv4_tunnel tun_key; 97 struct ovs_tunnel_info tun_info;
96 struct ovs_net *ovs_net; 98 struct ovs_net *ovs_net;
97 struct vport *vport; 99 struct vport *vport;
98 __be64 key; 100 __be64 key;
@@ -103,10 +105,10 @@ static int gre_rcv(struct sk_buff *skb,
103 return PACKET_REJECT; 105 return PACKET_REJECT;
104 106
105 key = key_to_tunnel_id(tpi->key, tpi->seq); 107 key = key_to_tunnel_id(tpi->key, tpi->seq);
106 ovs_flow_tun_key_init(&tun_key, ip_hdr(skb), key, 108 ovs_flow_tun_info_init(&tun_info, ip_hdr(skb), key,
107 filter_tnl_flags(tpi->flags)); 109 filter_tnl_flags(tpi->flags));
108 110
109 ovs_vport_receive(vport, skb, &tun_key); 111 ovs_vport_receive(vport, skb, &tun_info);
110 return PACKET_RCVD; 112 return PACKET_RCVD;
111} 113}
112 114
@@ -137,12 +139,12 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
137 __be16 df; 139 __be16 df;
138 int err; 140 int err;
139 141
140 if (unlikely(!OVS_CB(skb)->egress_tun_key)) { 142 if (unlikely(!OVS_CB(skb)->egress_tun_info)) {
141 err = -EINVAL; 143 err = -EINVAL;
142 goto error; 144 goto error;
143 } 145 }
144 146
145 tun_key = OVS_CB(skb)->egress_tun_key; 147 tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
146 /* Route lookup */ 148 /* Route lookup */
147 memset(&fl, 0, sizeof(fl)); 149 memset(&fl, 0, sizeof(fl));
148 fl.daddr = tun_key->ipv4_dst; 150 fl.daddr = tun_key->ipv4_dst;
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
index f19539bb8adc..5fbff2c1ee49 100644
--- a/net/openvswitch/vport-vxlan.c
+++ b/net/openvswitch/vport-vxlan.c
@@ -58,7 +58,7 @@ static inline struct vxlan_port *vxlan_vport(const struct vport *vport)
58/* Called with rcu_read_lock and BH disabled. */ 58/* Called with rcu_read_lock and BH disabled. */
59static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb, __be32 vx_vni) 59static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb, __be32 vx_vni)
60{ 60{
61 struct ovs_key_ipv4_tunnel tun_key; 61 struct ovs_tunnel_info tun_info;
62 struct vport *vport = vs->data; 62 struct vport *vport = vs->data;
63 struct iphdr *iph; 63 struct iphdr *iph;
64 __be64 key; 64 __be64 key;
@@ -66,9 +66,9 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb, __be32 vx_vni)
66 /* Save outer tunnel values */ 66 /* Save outer tunnel values */
67 iph = ip_hdr(skb); 67 iph = ip_hdr(skb);
68 key = cpu_to_be64(ntohl(vx_vni) >> 8); 68 key = cpu_to_be64(ntohl(vx_vni) >> 8);
69 ovs_flow_tun_key_init(&tun_key, iph, key, TUNNEL_KEY); 69 ovs_flow_tun_info_init(&tun_info, iph, key, TUNNEL_KEY);
70 70
71 ovs_vport_receive(vport, skb, &tun_key); 71 ovs_vport_receive(vport, skb, &tun_info);
72} 72}
73 73
74static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb) 74static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb)
@@ -147,12 +147,12 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
147 __be16 df; 147 __be16 df;
148 int err; 148 int err;
149 149
150 if (unlikely(!OVS_CB(skb)->egress_tun_key)) { 150 if (unlikely(!OVS_CB(skb)->egress_tun_info)) {
151 err = -EINVAL; 151 err = -EINVAL;
152 goto error; 152 goto error;
153 } 153 }
154 154
155 tun_key = OVS_CB(skb)->egress_tun_key; 155 tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
156 /* Route lookup */ 156 /* Route lookup */
157 memset(&fl, 0, sizeof(fl)); 157 memset(&fl, 0, sizeof(fl));
158 fl.daddr = tun_key->ipv4_dst; 158 fl.daddr = tun_key->ipv4_dst;
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index 5df8377fcfb1..3e50ee8a218c 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -432,7 +432,7 @@ u32 ovs_vport_find_upcall_portid(const struct vport *p, struct sk_buff *skb)
432 * skb->data should point to the Ethernet header. 432 * skb->data should point to the Ethernet header.
433 */ 433 */
434void ovs_vport_receive(struct vport *vport, struct sk_buff *skb, 434void ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
435 struct ovs_key_ipv4_tunnel *tun_key) 435 struct ovs_tunnel_info *tun_info)
436{ 436{
437 struct pcpu_sw_netstats *stats; 437 struct pcpu_sw_netstats *stats;
438 struct sw_flow_key key; 438 struct sw_flow_key key;
@@ -445,9 +445,9 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
445 u64_stats_update_end(&stats->syncp); 445 u64_stats_update_end(&stats->syncp);
446 446
447 OVS_CB(skb)->input_vport = vport; 447 OVS_CB(skb)->input_vport = vport;
448 OVS_CB(skb)->egress_tun_key = NULL; 448 OVS_CB(skb)->egress_tun_info = NULL;
449 /* Extract flow from 'skb' into 'key'. */ 449 /* Extract flow from 'skb' into 'key'. */
450 error = ovs_flow_key_extract(tun_key, skb, &key); 450 error = ovs_flow_key_extract(tun_info, skb, &key);
451 if (unlikely(error)) { 451 if (unlikely(error)) {
452 kfree_skb(skb); 452 kfree_skb(skb);
453 return; 453 return;
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h
index 0efd62fef1e8..e28964aba021 100644
--- a/net/openvswitch/vport.h
+++ b/net/openvswitch/vport.h
@@ -207,7 +207,7 @@ static inline struct vport *vport_from_priv(void *priv)
207} 207}
208 208
209void ovs_vport_receive(struct vport *, struct sk_buff *, 209void ovs_vport_receive(struct vport *, struct sk_buff *,
210 struct ovs_key_ipv4_tunnel *); 210 struct ovs_tunnel_info *);
211 211
212/* List of statically compiled vport implementations. Don't forget to also 212/* List of statically compiled vport implementations. Don't forget to also
213 * add yours to the list at the top of vport.c. */ 213 * add yours to the list at the top of vport.c. */