aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/flow_netlink.c
diff options
context:
space:
mode:
authorWenyu Zhang <wenyuz@vmware.com>2014-11-06 09:51:24 -0500
committerPravin B Shelar <pshelar@nicira.com>2014-11-09 21:58:44 -0500
commit8f0aad6f35f7e8b3118b7b8a65e8e76b135cc4cb (patch)
tree5f3dd8374c3c1584cb2b516f4191e70b82472f68 /net/openvswitch/flow_netlink.c
parent9ba559d9ca3711940be3e7207dac13c4f0654d43 (diff)
openvswitch: Extend packet attribute for egress tunnel info
OVS vswitch has extended IPFIX exporter to export tunnel headers to improve network visibility. To export this information userspace needs to know egress tunnel for given packet. By extending packet attributes datapath can export egress tunnel info for given packet. So that userspace can ask for egress tunnel info in userspace action. This information is used to build IPFIX data for given flow. Signed-off-by: Wenyu Zhang <wenyuz@vmware.com> Acked-by: Romain Lenglet <rlenglet@vmware.com> Acked-by: Ben Pfaff <blp@nicira.com> Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Diffstat (limited to 'net/openvswitch/flow_netlink.c')
-rw-r--r--net/openvswitch/flow_netlink.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index ed3109761827..98a3e96b7d93 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -245,6 +245,24 @@ static bool match_validate(const struct sw_flow_match *match,
245 return true; 245 return true;
246} 246}
247 247
248size_t ovs_tun_key_attr_size(void)
249{
250 /* Whenever adding new OVS_TUNNEL_KEY_ FIELDS, we should consider
251 * updating this function.
252 */
253 return nla_total_size(8) /* OVS_TUNNEL_KEY_ATTR_ID */
254 + nla_total_size(4) /* OVS_TUNNEL_KEY_ATTR_IPV4_SRC */
255 + nla_total_size(4) /* OVS_TUNNEL_KEY_ATTR_IPV4_DST */
256 + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TOS */
257 + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TTL */
258 + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */
259 + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_CSUM */
260 + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_OAM */
261 + nla_total_size(256) /* OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS */
262 + nla_total_size(2) /* OVS_TUNNEL_KEY_ATTR_TP_SRC */
263 + nla_total_size(2); /* OVS_TUNNEL_KEY_ATTR_TP_DST */
264}
265
248size_t ovs_key_attr_size(void) 266size_t ovs_key_attr_size(void)
249{ 267{
250 /* Whenever adding new OVS_KEY_ FIELDS, we should consider 268 /* Whenever adding new OVS_KEY_ FIELDS, we should consider
@@ -254,15 +272,7 @@ size_t ovs_key_attr_size(void)
254 272
255 return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */ 273 return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */
256 + nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */ 274 + nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */
257 + nla_total_size(8) /* OVS_TUNNEL_KEY_ATTR_ID */ 275 + ovs_tun_key_attr_size()
258 + nla_total_size(4) /* OVS_TUNNEL_KEY_ATTR_IPV4_SRC */
259 + nla_total_size(4) /* OVS_TUNNEL_KEY_ATTR_IPV4_DST */
260 + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TOS */
261 + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TTL */
262 + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */
263 + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_CSUM */
264 + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_OAM */
265 + nla_total_size(256) /* OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS */
266 + nla_total_size(4) /* OVS_KEY_ATTR_IN_PORT */ 276 + nla_total_size(4) /* OVS_KEY_ATTR_IN_PORT */
267 + nla_total_size(4) /* OVS_KEY_ATTR_SKB_MARK */ 277 + nla_total_size(4) /* OVS_KEY_ATTR_SKB_MARK */
268 + nla_total_size(4) /* OVS_KEY_ATTR_DP_HASH */ 278 + nla_total_size(4) /* OVS_KEY_ATTR_DP_HASH */
@@ -393,6 +403,8 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
393 [OVS_TUNNEL_KEY_ATTR_TTL] = 1, 403 [OVS_TUNNEL_KEY_ATTR_TTL] = 1,
394 [OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT] = 0, 404 [OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT] = 0,
395 [OVS_TUNNEL_KEY_ATTR_CSUM] = 0, 405 [OVS_TUNNEL_KEY_ATTR_CSUM] = 0,
406 [OVS_TUNNEL_KEY_ATTR_TP_SRC] = sizeof(u16),
407 [OVS_TUNNEL_KEY_ATTR_TP_DST] = sizeof(u16),
396 [OVS_TUNNEL_KEY_ATTR_OAM] = 0, 408 [OVS_TUNNEL_KEY_ATTR_OAM] = 0,
397 [OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS] = -1, 409 [OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS] = -1,
398 }; 410 };
@@ -440,6 +452,14 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
440 case OVS_TUNNEL_KEY_ATTR_CSUM: 452 case OVS_TUNNEL_KEY_ATTR_CSUM:
441 tun_flags |= TUNNEL_CSUM; 453 tun_flags |= TUNNEL_CSUM;
442 break; 454 break;
455 case OVS_TUNNEL_KEY_ATTR_TP_SRC:
456 SW_FLOW_KEY_PUT(match, tun_key.tp_src,
457 nla_get_be16(a), is_mask);
458 break;
459 case OVS_TUNNEL_KEY_ATTR_TP_DST:
460 SW_FLOW_KEY_PUT(match, tun_key.tp_dst,
461 nla_get_be16(a), is_mask);
462 break;
443 case OVS_TUNNEL_KEY_ATTR_OAM: 463 case OVS_TUNNEL_KEY_ATTR_OAM:
444 tun_flags |= TUNNEL_OAM; 464 tun_flags |= TUNNEL_OAM;
445 break; 465 break;
@@ -548,6 +568,12 @@ static int __ipv4_tun_to_nlattr(struct sk_buff *skb,
548 if ((output->tun_flags & TUNNEL_CSUM) && 568 if ((output->tun_flags & TUNNEL_CSUM) &&
549 nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_CSUM)) 569 nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_CSUM))
550 return -EMSGSIZE; 570 return -EMSGSIZE;
571 if (output->tp_src &&
572 nla_put_be16(skb, OVS_TUNNEL_KEY_ATTR_TP_SRC, output->tp_src))
573 return -EMSGSIZE;
574 if (output->tp_dst &&
575 nla_put_be16(skb, OVS_TUNNEL_KEY_ATTR_TP_DST, output->tp_dst))
576 return -EMSGSIZE;
551 if ((output->tun_flags & TUNNEL_OAM) && 577 if ((output->tun_flags & TUNNEL_OAM) &&
552 nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_OAM)) 578 nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_OAM))
553 return -EMSGSIZE; 579 return -EMSGSIZE;
@@ -559,7 +585,6 @@ static int __ipv4_tun_to_nlattr(struct sk_buff *skb,
559 return 0; 585 return 0;
560} 586}
561 587
562
563static int ipv4_tun_to_nlattr(struct sk_buff *skb, 588static int ipv4_tun_to_nlattr(struct sk_buff *skb,
564 const struct ovs_key_ipv4_tunnel *output, 589 const struct ovs_key_ipv4_tunnel *output,
565 const struct geneve_opt *tun_opts, 590 const struct geneve_opt *tun_opts,
@@ -580,6 +605,14 @@ static int ipv4_tun_to_nlattr(struct sk_buff *skb,
580 return 0; 605 return 0;
581} 606}
582 607
608int ovs_nla_put_egress_tunnel_key(struct sk_buff *skb,
609 const struct ovs_tunnel_info *egress_tun_info)
610{
611 return __ipv4_tun_to_nlattr(skb, &egress_tun_info->tunnel,
612 egress_tun_info->options,
613 egress_tun_info->options_len);
614}
615
583static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, 616static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs,
584 const struct nlattr **a, bool is_mask) 617 const struct nlattr **a, bool is_mask)
585{ 618{
@@ -1653,6 +1686,7 @@ static int validate_userspace(const struct nlattr *attr)
1653 static const struct nla_policy userspace_policy[OVS_USERSPACE_ATTR_MAX + 1] = { 1686 static const struct nla_policy userspace_policy[OVS_USERSPACE_ATTR_MAX + 1] = {
1654 [OVS_USERSPACE_ATTR_PID] = {.type = NLA_U32 }, 1687 [OVS_USERSPACE_ATTR_PID] = {.type = NLA_U32 },
1655 [OVS_USERSPACE_ATTR_USERDATA] = {.type = NLA_UNSPEC }, 1688 [OVS_USERSPACE_ATTR_USERDATA] = {.type = NLA_UNSPEC },
1689 [OVS_USERSPACE_ATTR_EGRESS_TUN_PORT] = {.type = NLA_U32 },
1656 }; 1690 };
1657 struct nlattr *a[OVS_USERSPACE_ATTR_MAX + 1]; 1691 struct nlattr *a[OVS_USERSPACE_ATTR_MAX + 1];
1658 int error; 1692 int error;