[ovs-dev] [PATCH 2/2] ofproto-dpif-ipfix: add interface Information Elements to flow key
Greg Rose
gvrose8192 at gmail.com
Fri Sep 8 14:55:29 UTC 2017
On 09/08/2017 06:35 AM, Weglicki, MichalX wrote:
> Greg,
>
> Patch is rebased and sent to mailing list as V3 (Last patch was supposed to be V2 - Przemek by accident sent it again as V1).
>
> Br,
> Michal.
Thanks, I'll have a look at it!
- Greg
>
> > -----Original Message-----
> > From: Greg Rose [mailto:gvrose8192 at gmail.com]
> > Sent: Thursday, September 7, 2017 12:02 AM
> > To: Weglicki, MichalX <michalx.weglicki at intel.com>
> > Cc: dev at openvswitch.org; Szczerbik, PrzemyslawX <przemyslawx.szczerbik at intel.com>
> > Subject: Re: [ovs-dev] [PATCH 2/2] ofproto-dpif-ipfix: add interface Information Elements to flow key
> >
> > On 09/06/2017 02:53 AM, Weglicki, MichalX wrote:
> >> Hey Greg,
> >>
> >> Do you have any schedule for checking this patch?
> >>
> >> Thank you in advance!
> >>
> >> Br,
> >> Michal.
> >
> > Michal,
> >
> > The good news is that I have my ntopng/nprobe ipfix collector properly configured now and can see
> > flows, hosts, etc. when I enable IPFIX. So I'm ready to test these two patches from Przemyslaw:
> >
> > https://patchwork.ozlabs.org/patch/793773/
> > https://patchwork.ozlabs.org/patch/793772/
> >
> > Unfortunately the patches no longer apply to master.
> >
> > Can you rebase and resubmit a V3 series?
> >
> > Thanks,
> >
> > - Greg
> >
> >>
> >>> -----Original Message-----
> >>> From: Greg Rose [mailto:gvrose8192 at gmail.com]
> >>> Sent: Tuesday, August 29, 2017 5:15 PM
> >>> To: Weglicki, MichalX <michalx.weglicki at intel.com>
> >>> Cc: dev at openvswitch.org; Szczerbik, PrzemyslawX <przemyslawx.szczerbik at intel.com>
> >>> Subject: Re: [ovs-dev] [PATCH 2/2] ofproto-dpif-ipfix: add interface Information Elements to flow key
> >>>
> >>> On 08/29/2017 04:48 AM, Weglicki, MichalX wrote:
> >>>> Hello Greg,
> >>>>
> >>>> Unfortunately Przemek is not available, but I'm more or less familiar with this patch.
> >>>>
> >>>> Did you manage to fix this issue? I think that your problems lies on connection level, which wasn't modified by this patch. Patch
> >>> added additional counters on reporting level, and based on your description, ovs just can't connect to collector.
> >>>>
> >>>> Br,
> >>>> Michal.
> >>>
> >>> Correct - it is not an issue with the patch. However, I need to test the patch and ran into problems while trying to do so. Since
> > then
> >>> I've been pulled into some other work and will get back to this afterwards. I'll just need to debug the connection issue to the
> >>> collector.
> >>>
> >>> Thanks,
> >>>
> >>> - Greg
> >>>
> >>>>
> >>>>> -----Original Message-----
> >>>>> From: ovs-dev-bounces at openvswitch.org [mailto:ovs-dev-bounces at openvswitch.org] On Behalf Of Greg Rose
> >>>>> Sent: Saturday, August 19, 2017 12:51 AM
> >>>>> To: Szczerbik, PrzemyslawX <przemyslawx.szczerbik at intel.com>
> >>>>> Cc: dev at openvswitch.org
> >>>>> Subject: Re: [ovs-dev] [PATCH 2/2] ofproto-dpif-ipfix: add interface Information Elements to flow key
> >>>>>
> >>>>> On 08/16/2017 01:54 AM, Szczerbik, PrzemyslawX wrote:
> >>>>>> Hi,
> >>>>>>
> >>>>>> I haven't received any feedback on this patch for quite some time.
> >>>>>> Is there anything that I can do to expedite review process?
> >>>>>>
> >>>>>> Regards,
> >>>>>> Przemek
> >>>>>>
> >>>>>
> >>>>> Przemek,
> >>>>>
> >>>>> I'm in the process of looking into this patch but I'm running into an issue with the vswitch not sending flows to the
> >>> ntopng/nprobe
> >>>>> collector I have set up. I see this in the vswitchd log:
> >>>>>
> >>>>> 2017-08-18T21:48:57.917Z|00058|collectors|WARN|couldn't open connection to collector 192.168.0.21:2055 (Network is
> >>>>> unreachable)
> >>>>> 2017-08-18T21:48:57.917Z|00059|ipfix|WARN|no collectors could be initialized, IPFIX exporter disabled
> >>>>>
> >>>>> However, 192.168.0.21 is reachable, at least from the br0 bridge that has the IPFIX flows enabled.
> >>>>>
> >>>>> ntopng/nprobe on the collector machine has the right ports open:
> >>>>>
> >>>>> netstat -tulpen | grep 2055
> >>>>> udp 0 0 0.0.0.0:2055 0.0.0.0:* 99 27671 3038/nprobe
> >>>>> udp6 0 0 :::2055 :::* 99 27672 3038/nprobe
> >>>>>
> >>>>> netstat -tulpen | grep 5556
> >>>>> tcp 0 0 0.0.0.0:5556 0.0.0.0:* LISTEN 0 27666 3038/nprobe
> >>>>>
> >>>>> I'm not sure exactly what the problem is but I'm debugging that. Until I can get past this issue I can't really test and review
> > your
> >>>>> patch. I am actively working on getting this issue fixed though.
> >>>>>
> >>>>> Regards,
> >>>>>
> >>>>> - Greg
> >>>>>>> -----Original Message-----
> >>>>>>> From: ovs-dev-bounces at openvswitch.org [mailto:ovs-dev-
> >>>>>>> bounces at openvswitch.org] On Behalf Of Szczerbik, PrzemyslawX
> >>>>>>> Sent: Wednesday, July 26, 2017 12:01 PM
> >>>>>>> To: dev at openvswitch.org
> >>>>>>> Subject: Re: [ovs-dev] [PATCH 2/2] ofproto-dpif-ipfix: add interface Information
> >>>>>>> Elements to flow key
> >>>>>>>
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> This patch was supposed to be v2, but I forgot to mention that in the subject.
> >>>>>>> Previous version: https://patchwork.ozlabs.org/patch/792730/
> >>>>>>>
> >>>>>>> Let me know if you want me to re-sent it with a proper version.
> >>>>>>>
> >>>>>>> Regards,
> >>>>>>> Przemek
> >>>>>>>
> >>>>>>>> -----Original Message-----
> >>>>>>>> From: Szczerbik, PrzemyslawX
> >>>>>>>> Sent: Wednesday, July 26, 2017 10:44 AM
> >>>>>>>> To: dev at openvswitch.org
> >>>>>>>> Cc: Szczerbik, PrzemyslawX <przemyslawx.szczerbik at intel.com>
> >>>>>>>> Subject: [PATCH 2/2] ofproto-dpif-ipfix: add interface Information Elements to
> >>>>>>>> flow key
> >>>>>>>>
> >>>>>>>> Extend flow key part of data record to include following Information Elements:
> >>>>>>>> - ingressInterface
> >>>>>>>> - ingressInterfaceType
> >>>>>>>> - egressInterface
> >>>>>>>> - egressInterfaceType
> >>>>>>>> - interfaceName
> >>>>>>>> - interfaceDescription
> >>>>>>>>
> >>>>>>>> In case of input sampling we don't have information about egress port.
> >>>>>>>> Define templates depending not only on protocol types, but also on flow
> >>>>>>>> direction. Only egress flow will include egress information elements.
> >>>>>>>>
> >>>>>>>> With this change, dpif_ipfix_exporter stores every port in hmap rather
> >>>>>>>> than only tunnel ports. It allows to easily retrieve required
> >>>>>>>> information about interfaces during sampling upcalls.
> >>>>>>>>
> >>>>>>>> Signed-off-by: Przemyslaw Szczerbik <przemyslawx.szczerbik at intel.com>
> >>>>>>>> ---
> >>>>>>>> v1->v2
> >>>>>>>> * Add interfaceType and interfaceDescription
> >>>>>>>> * Rework ipfix_get_iface_data_record function
> >>>>>>>>
> >>>>>>>> ofproto/ofproto-dpif-ipfix.c | 356 +++++++++++++++++++++++++++++++-----
> >>>>>>> --
> >>>>>>>> -----
> >>>>>>>> ofproto/ofproto-dpif-ipfix.h | 6 +-
> >>>>>>>> ofproto/ofproto-dpif-xlate.c | 4 +-
> >>>>>>>> ofproto/ofproto-dpif.c | 19 +--
> >>>>>>>> 4 files changed, 275 insertions(+), 110 deletions(-)
> >>>>>>>>
> >>>>>>>> diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c
> >>>>>>>> index 13ff426..e7ce279 100644
> >>>>>>>> --- a/ofproto/ofproto-dpif-ipfix.c
> >>>>>>>> +++ b/ofproto/ofproto-dpif-ipfix.c
> >>>>>>>> @@ -113,11 +113,12 @@ struct dpif_ipfix_global_stats {
> >>>>>>>> };
> >>>>>>>>
> >>>>>>>> struct dpif_ipfix_port {
> >>>>>>>> - struct hmap_node hmap_node; /* In struct dpif_ipfix's "tunnel_ports"
> >>>>>>> hmap.
> >>>>>>>> */
> >>>>>>>> + struct hmap_node hmap_node; /* In struct dpif_ipfix's "ports" hmap. */
> >>>>>>>> struct ofport *ofport; /* To retrieve port stats. */
> >>>>>>>> odp_port_t odp_port;
> >>>>>>>> enum dpif_ipfix_tunnel_type tunnel_type;
> >>>>>>>> uint8_t tunnel_key_length;
> >>>>>>>> + uint32_t ifindex;
> >>>>>>>> };
> >>>>>>>>
> >>>>>>>> struct dpif_ipfix_exporter {
> >>>>>>>> @@ -155,9 +156,9 @@ struct dpif_ipfix_flow_exporter_map_node {
> >>>>>>>> struct dpif_ipfix {
> >>>>>>>> struct dpif_ipfix_bridge_exporter bridge_exporter;
> >>>>>>>> struct hmap flow_exporter_map; /* dpif_ipfix_flow_exporter_map_node.
> >>>>>>> */
> >>>>>>>> - struct hmap tunnel_ports; /* Contains "struct dpif_ipfix_port"s.
> >>>>>>>> - * It makes tunnel port lookups faster in
> >>>>>>>> - * sampling upcalls. */
> >>>>>>>> + struct hmap ports; /* Contains "struct dpif_ipfix_port"s.
> >>>>>>>> + * It makes port lookups faster in sampling
> >>>>>>>> + * upcalls. */
> >>>>>>>> struct ovs_refcount ref_cnt;
> >>>>>>>> };
> >>>>>>>>
> >>>>>>>> @@ -291,7 +292,8 @@ BUILD_ASSERT_DECL(sizeof(struct
> >>>>>>>> ipfix_template_field_specifier) == 8);
> >>>>>>>> /* Cf. IETF RFC 5102 Section 5.11.6. */
> >>>>>>>> enum ipfix_flow_direction {
> >>>>>>>> INGRESS_FLOW = 0x00,
> >>>>>>>> - EGRESS_FLOW = 0x01
> >>>>>>>> + EGRESS_FLOW = 0x01,
> >>>>>>>> + NUM_IPFIX_FLOW_DIRECTION
> >>>>>>>> };
> >>>>>>>>
> >>>>>>>> /* Part of data record flow key for common metadata and Ethernet entities. */
> >>>>>>>> @@ -306,6 +308,18 @@ struct ipfix_data_record_flow_key_common {
> >>>>>>>> });
> >>>>>>>> BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_flow_key_common) ==
> >>>>>>>> 20);
> >>>>>>>>
> >>>>>>>> +/* Part of data record flow key for interface information. Since some of the
> >>>>>>>> + * elements have variable length, members of this structure should be
> >>>>>>>> appended
> >>>>>>>> + * to the 'struct dp_packet' one by one. */
> >>>>>>>> +struct ipfix_data_record_flow_key_iface {
> >>>>>>>> + ovs_be32 if_index; /* (INGRESS|EGRESS)_INTERFACE */
> >>>>>>>> + ovs_be32 if_type; /* (INGRESS|EGRESS)_INTERFACE_TYPE */
> >>>>>>>> + uint8_t if_name_len; /* Variable length element: INTERFACE_NAME */
> >>>>>>>> + char *if_name;
> >>>>>>>> + uint8_t if_descr_len; /* Variable length element: INTERFACE_DESCRIPTION
> >>>>>>> */
> >>>>>>>> + char *if_descr;
> >>>>>>>> +};
> >>>>>>>> +
> >>>>>>>> /* Part of data record flow key for VLAN entities. */
> >>>>>>>> OVS_PACKED(
> >>>>>>>> struct ipfix_data_record_flow_key_vlan {
> >>>>>>>> @@ -735,7 +749,7 @@ dpif_ipfix_find_port(const struct dpif_ipfix *di,
> >>>>>>>> struct dpif_ipfix_port *dip;
> >>>>>>>>
> >>>>>>>> HMAP_FOR_EACH_IN_BUCKET (dip, hmap_node,
> >>>>>>> hash_odp_port(odp_port),
> >>>>>>>> - &di->tunnel_ports) {
> >>>>>>>> + &di->ports) {
> >>>>>>>> if (dip->odp_port == odp_port) {
> >>>>>>>> return dip;
> >>>>>>>> }
> >>>>>>>> @@ -744,82 +758,114 @@ dpif_ipfix_find_port(const struct dpif_ipfix *di,
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> static void
> >>>>>>>> -dpif_ipfix_del_port(struct dpif_ipfix *di,
> >>>>>>>> +dpif_ipfix_del_port__(struct dpif_ipfix *di,
> >>>>>>>> struct dpif_ipfix_port *dip)
> >>>>>>>> OVS_REQUIRES(mutex)
> >>>>>>>> {
> >>>>>>>> - hmap_remove(&di->tunnel_ports, &dip->hmap_node);
> >>>>>>>> + hmap_remove(&di->ports, &dip->hmap_node);
> >>>>>>>> free(dip);
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> +static enum dpif_ipfix_tunnel_type
> >>>>>>>> +dpif_ipfix_tunnel_type(const struct ofport *ofport) {
> >>>>>>>> + const char *type = netdev_get_type(ofport->netdev);
> >>>>>>>> +
> >>>>>>>> + if (type == NULL) {
> >>>>>>>> + return DPIF_IPFIX_TUNNEL_UNKNOWN;
> >>>>>>>> + }
> >>>>>>>> + if (strcmp(type, "gre") == 0) {
> >>>>>>>> + return DPIF_IPFIX_TUNNEL_GRE;
> >>>>>>>> + } else if (strcmp(type, "vxlan") == 0) {
> >>>>>>>> + return DPIF_IPFIX_TUNNEL_VXLAN;
> >>>>>>>> + } else if (strcmp(type, "lisp") == 0) {
> >>>>>>>> + return DPIF_IPFIX_TUNNEL_LISP;
> >>>>>>>> + } else if (strcmp(type, "geneve") == 0) {
> >>>>>>>> + return DPIF_IPFIX_TUNNEL_GENEVE;
> >>>>>>>> + } else if (strcmp(type, "stt") == 0) {
> >>>>>>>> + return DPIF_IPFIX_TUNNEL_STT;
> >>>>>>>> + }
> >>>>>>>> +
> >>>>>>>> + return DPIF_IPFIX_TUNNEL_UNKNOWN;
> >>>>>>>> +}
> >>>>>>>> +
> >>>>>>>> +static uint8_t
> >>>>>>>> +dpif_ipfix_tunnel_key_length(enum dpif_ipfix_tunnel_type tunnel_type) {
> >>>>>>>> +
> >>>>>>>> + switch (tunnel_type) {
> >>>>>>>> + case DPIF_IPFIX_TUNNEL_GRE:
> >>>>>>>> + /* 32-bit key gre */
> >>>>>>>> + return 4;
> >>>>>>>> + case DPIF_IPFIX_TUNNEL_VXLAN:
> >>>>>>>> + case DPIF_IPFIX_TUNNEL_LISP:
> >>>>>>>> + case DPIF_IPFIX_TUNNEL_GENEVE:
> >>>>>>>> + return 3;
> >>>>>>>> + case DPIF_IPFIX_TUNNEL_STT:
> >>>>>>>> + return 8;
> >>>>>>>> + case DPIF_IPFIX_TUNNEL_UNKNOWN:
> >>>>>>>> + case NUM_DPIF_IPFIX_TUNNEL:
> >>>>>>>> + default:
> >>>>>>>> + return 0;
> >>>>>>>> + }
> >>>>>>>> +}
> >>>>>>>> +
> >>>>>>>> void
> >>>>>>>> -dpif_ipfix_add_tunnel_port(struct dpif_ipfix *di, struct ofport *ofport,
> >>>>>>>> - odp_port_t odp_port) OVS_EXCLUDED(mutex)
> >>>>>>>> +dpif_ipfix_add_port(struct dpif_ipfix *di, struct ofport *ofport,
> >>>>>>>> + odp_port_t odp_port) OVS_EXCLUDED(mutex)
> >>>>>>>> {
> >>>>>>>> struct dpif_ipfix_port *dip;
> >>>>>>>> - const char *type;
> >>>>>>>> + int64_t ifindex;
> >>>>>>>>
> >>>>>>>> ovs_mutex_lock(&mutex);
> >>>>>>>> dip = dpif_ipfix_find_port(di, odp_port);
> >>>>>>>> if (dip) {
> >>>>>>>> - dpif_ipfix_del_port(di, dip);
> >>>>>>>> + dpif_ipfix_del_port__(di, dip);
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> - type = netdev_get_type(ofport->netdev);
> >>>>>>>> - if (type == NULL) {
> >>>>>>>> - goto out;
> >>>>>>>> + ifindex = netdev_get_ifindex(ofport->netdev);
> >>>>>>>> + if (ifindex < 0) {
> >>>>>>>> + ifindex = 0;
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> - /* Add to table of tunnel ports. */
> >>>>>>>> + /* Add to table of ports. */
> >>>>>>>> dip = xmalloc(sizeof *dip);
> >>>>>>>> dip->ofport = ofport;
> >>>>>>>> dip->odp_port = odp_port;
> >>>>>>>> - if (strcmp(type, "gre") == 0) {
> >>>>>>>> - /* 32-bit key gre */
> >>>>>>>> - dip->tunnel_type = DPIF_IPFIX_TUNNEL_GRE;
> >>>>>>>> - dip->tunnel_key_length = 4;
> >>>>>>>> - } else if (strcmp(type, "vxlan") == 0) {
> >>>>>>>> - dip->tunnel_type = DPIF_IPFIX_TUNNEL_VXLAN;
> >>>>>>>> - dip->tunnel_key_length = 3;
> >>>>>>>> - } else if (strcmp(type, "lisp") == 0) {
> >>>>>>>> - dip->tunnel_type = DPIF_IPFIX_TUNNEL_LISP;
> >>>>>>>> - dip->tunnel_key_length = 3;
> >>>>>>>> - } else if (strcmp(type, "geneve") == 0) {
> >>>>>>>> - dip->tunnel_type = DPIF_IPFIX_TUNNEL_GENEVE;
> >>>>>>>> - dip->tunnel_key_length = 3;
> >>>>>>>> - } else if (strcmp(type, "stt") == 0) {
> >>>>>>>> - dip->tunnel_type = DPIF_IPFIX_TUNNEL_STT;
> >>>>>>>> - dip->tunnel_key_length = 8;
> >>>>>>>> - } else {
> >>>>>>>> - free(dip);
> >>>>>>>> - goto out;
> >>>>>>>> - }
> >>>>>>>> - hmap_insert(&di->tunnel_ports, &dip->hmap_node,
> >>>>>>>> hash_odp_port(odp_port));
> >>>>>>>> + dip->tunnel_type = dpif_ipfix_tunnel_type(ofport);
> >>>>>>>> + dip->tunnel_key_length = dpif_ipfix_tunnel_key_length(dip-
> >>>>>>>> tunnel_type);
> >>>>>>>> + dip->ifindex = ifindex;
> >>>>>>>> + hmap_insert(&di->ports, &dip->hmap_node, hash_odp_port(odp_port));
> >>>>>>>>
> >>>>>>>> -out:
> >>>>>>>> ovs_mutex_unlock(&mutex);
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> void
> >>>>>>>> -dpif_ipfix_del_tunnel_port(struct dpif_ipfix *di, odp_port_t odp_port)
> >>>>>>>> +dpif_ipfix_del_port(struct dpif_ipfix *di, odp_port_t odp_port)
> >>>>>>>> OVS_EXCLUDED(mutex)
> >>>>>>>> {
> >>>>>>>> struct dpif_ipfix_port *dip;
> >>>>>>>> ovs_mutex_lock(&mutex);
> >>>>>>>> dip = dpif_ipfix_find_port(di, odp_port);
> >>>>>>>> if (dip) {
> >>>>>>>> - dpif_ipfix_del_port(di, dip);
> >>>>>>>> + dpif_ipfix_del_port__(di, dip);
> >>>>>>>> }
> >>>>>>>> ovs_mutex_unlock(&mutex);
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> +static struct dpif_ipfix_port *
> >>>>>>>> +dpif_ipfix_find_tunnel_port(const struct dpif_ipfix *di, odp_port_t odp_port)
> >>>>>>>> + OVS_REQUIRES(mutex)
> >>>>>>>> +{
> >>>>>>>> + struct dpif_ipfix_port *dip = dpif_ipfix_find_port(di, odp_port);
> >>>>>>>> + return (dip && dip->tunnel_type != DPIF_IPFIX_TUNNEL_UNKNOWN) ? dip
> >>>>>>> :
> >>>>>>>> NULL;
> >>>>>>>> +}
> >>>>>>>> +
> >>>>>>>> bool
> >>>>>>>> -dpif_ipfix_get_tunnel_port(const struct dpif_ipfix *di, odp_port_t odp_port)
> >>>>>>>> +dpif_ipfix_is_tunnel_port(const struct dpif_ipfix *di, odp_port_t odp_port)
> >>>>>>>> OVS_EXCLUDED(mutex)
> >>>>>>>> {
> >>>>>>>> struct dpif_ipfix_port *dip;
> >>>>>>>> ovs_mutex_lock(&mutex);
> >>>>>>>> - dip = dpif_ipfix_find_port(di, odp_port);
> >>>>>>>> + dip = dpif_ipfix_find_tunnel_port(di, odp_port);
> >>>>>>>> ovs_mutex_unlock(&mutex);
> >>>>>>>> return dip != NULL;
> >>>>>>>> }
> >>>>>>>> @@ -1055,7 +1101,7 @@ dpif_ipfix_create(void)
> >>>>>>>> di = xzalloc(sizeof *di);
> >>>>>>>> dpif_ipfix_bridge_exporter_init(&di->bridge_exporter);
> >>>>>>>> hmap_init(&di->flow_exporter_map);
> >>>>>>>> - hmap_init(&di->tunnel_ports);
> >>>>>>>> + hmap_init(&di->ports);
> >>>>>>>> ovs_refcount_init(&di->ref_cnt);
> >>>>>>>> return di;
> >>>>>>>> }
> >>>>>>>> @@ -1149,8 +1195,8 @@ dpif_ipfix_clear(struct dpif_ipfix *di)
> >>>>>>>> OVS_REQUIRES(mutex)
> >>>>>>>> free(exp_node);
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> - HMAP_FOR_EACH_SAFE (dip, next, hmap_node, &di->tunnel_ports) {
> >>>>>>>> - dpif_ipfix_del_port(di, dip);
> >>>>>>>> + HMAP_FOR_EACH_SAFE (dip, next, hmap_node, &di->ports) {
> >>>>>>>> + dpif_ipfix_del_port__(di, dip);
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> @@ -1162,7 +1208,7 @@ dpif_ipfix_unref(struct dpif_ipfix *di)
> >>>>>>>> OVS_EXCLUDED(mutex)
> >>>>>>>> dpif_ipfix_clear(di);
> >>>>>>>> dpif_ipfix_bridge_exporter_destroy(&di->bridge_exporter);
> >>>>>>>> hmap_destroy(&di->flow_exporter_map);
> >>>>>>>> - hmap_destroy(&di->tunnel_ports);
> >>>>>>>> + hmap_destroy(&di->ports);
> >>>>>>>> free(di);
> >>>>>>>> ovs_mutex_unlock(&mutex);
> >>>>>>>> }
> >>>>>>>> @@ -1201,13 +1247,15 @@ ipfix_send_msg(const struct collectors *collectors,
> >>>>>>>> struct dp_packet *msg)
> >>>>>>>>
> >>>>>>>> static uint16_t
> >>>>>>>> ipfix_get_template_id(enum ipfix_proto_l2 l2, enum ipfix_proto_l3 l3,
> >>>>>>>> - enum ipfix_proto_l4 l4, enum ipfix_proto_tunnel tunnel)
> >>>>>>>> + enum ipfix_proto_l4 l4, enum ipfix_proto_tunnel tunnel,
> >>>>>>>> + enum ipfix_flow_direction flow_direction)
> >>>>>>>> {
> >>>>>>>> uint16_t template_id;
> >>>>>>>> template_id = l2;
> >>>>>>>> template_id = template_id * NUM_IPFIX_PROTO_L3 + l3;
> >>>>>>>> template_id = template_id * NUM_IPFIX_PROTO_L4 + l4;
> >>>>>>>> template_id = template_id * NUM_IPFIX_PROTO_TUNNEL + tunnel;
> >>>>>>>> + template_id = template_id * NUM_IPFIX_FLOW_DIRECTION +
> >>>>>>> flow_direction;
> >>>>>>>> return IPFIX_TEMPLATE_ID_MIN + template_id;
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> @@ -1219,7 +1267,8 @@ ipfix_get_options_template_id(enum
> >>>>>>>> ipfix_options_template opt_tmpl_type)
> >>>>>>>> uint16_t max_tmpl_id = ipfix_get_template_id(NUM_IPFIX_PROTO_L2,
> >>>>>>>> NUM_IPFIX_PROTO_L3,
> >>>>>>>> NUM_IPFIX_PROTO_L4,
> >>>>>>>> - NUM_IPFIX_PROTO_TUNNEL);
> >>>>>>>> + NUM_IPFIX_PROTO_TUNNEL,
> >>>>>>>> + NUM_IPFIX_FLOW_DIRECTION);
> >>>>>>>>
> >>>>>>>> return max_tmpl_id + opt_tmpl_type;
> >>>>>>>> }
> >>>>>>>> @@ -1315,7 +1364,9 @@ ipfix_def_options_template_fields(enum
> >>>>>>>> ipfix_options_template opt_tmpl_type,
> >>>>>>>> static uint16_t
> >>>>>>>> ipfix_define_template_fields(enum ipfix_proto_l2 l2, enum ipfix_proto_l3 l3,
> >>>>>>>> enum ipfix_proto_l4 l4, enum ipfix_proto_tunnel tunnel,
> >>>>>>>> - bool virtual_obs_id_set, size_t tmpl_hdr_offset,
> >>>>>>>> + enum ipfix_flow_direction flow_direction,
> >>>>>>>> + bool virtual_obs_id_set,
> >>>>>>>> + size_t tmpl_hdr_offset,
> >>>>>>>> struct dp_packet *msg)
> >>>>>>>> {
> >>>>>>>>
> >>>>>>>> @@ -1333,6 +1384,19 @@ ipfix_define_template_fields(enum ipfix_proto_l2
> >>>>>>> l2,
> >>>>>>>> enum ipfix_proto_l3 l3,
> >>>>>>>> DEF(ETHERNET_TYPE);
> >>>>>>>> DEF(ETHERNET_HEADER_LENGTH);
> >>>>>>>>
> >>>>>>>> + /* Interface Information Elements */
> >>>>>>>> + DEF(INGRESS_INTERFACE);
> >>>>>>>> + DEF(INGRESS_INTERFACE_TYPE);
> >>>>>>>> + DEF(INTERFACE_NAME);
> >>>>>>>> + DEF(INTERFACE_DESCRIPTION);
> >>>>>>>> +
> >>>>>>>> + if (flow_direction == EGRESS_FLOW) {
> >>>>>>>> + DEF(EGRESS_INTERFACE);
> >>>>>>>> + DEF(EGRESS_INTERFACE_TYPE);
> >>>>>>>> + DEF(INTERFACE_NAME);
> >>>>>>>> + DEF(INTERFACE_DESCRIPTION);
> >>>>>>>> + }
> >>>>>>>> +
> >>>>>>>> if (l2 == IPFIX_PROTO_L2_VLAN) {
> >>>>>>>> DEF(VLAN_ID);
> >>>>>>>> DEF(DOT1Q_VLAN_ID);
> >>>>>>>> @@ -1530,6 +1594,24 @@ ipfix_send_options_template_msgs(struct
> >>>>>>>> dpif_ipfix_exporter *exporter,
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> static void
> >>>>>>>> +ipfix_add_template_record(enum ipfix_proto_l2 l2, enum ipfix_proto_l3 l3,
> >>>>>>>> + enum ipfix_proto_l4 l4,
> >>>>>>>> + enum ipfix_proto_tunnel tunnel,
> >>>>>>>> + enum ipfix_flow_direction flow_direction,
> >>>>>>>> + bool virtual_obs_id_set,
> >>>>>>>> + struct dp_packet *msg)
> >>>>>>>> +{
> >>>>>>>> + struct ipfix_template_record_header *tmpl_hdr;
> >>>>>>>> + size_t tmpl_hdr_offset = dp_packet_size(msg);
> >>>>>>>> +
> >>>>>>>> + tmpl_hdr = dp_packet_put_zeros(msg, sizeof *tmpl_hdr);
> >>>>>>>> + tmpl_hdr->template_id =
> >>>>>>>> + htons(ipfix_get_template_id(l2, l3, l4, tunnel, flow_direction));
> >>>>>>>> + ipfix_define_template_fields(l2, l3, l4, tunnel, flow_direction,
> >>>>>>>> + virtual_obs_id_set, tmpl_hdr_offset, msg);
> >>>>>>>> +}
> >>>>>>>> +
> >>>>>>>> +static void
> >>>>>>>> ipfix_send_template_msgs(struct dpif_ipfix_exporter *exporter,
> >>>>>>>> uint32_t export_time_sec, uint32_t obs_domain_id)
> >>>>>>>> {
> >>>>>>>> @@ -1537,14 +1619,14 @@ ipfix_send_template_msgs(struct
> >>>>>>>> dpif_ipfix_exporter *exporter,
> >>>>>>>> struct dp_packet msg;
> >>>>>>>> dp_packet_use_stub(&msg, msg_stub, sizeof msg_stub);
> >>>>>>>>
> >>>>>>>> - size_t set_hdr_offset, tmpl_hdr_offset, error_pkts;
> >>>>>>>> - struct ipfix_template_record_header *tmpl_hdr;
> >>>>>>>> + size_t set_hdr_offset, error_pkts;
> >>>>>>>> size_t tx_packets = 0;
> >>>>>>>> size_t tx_errors = 0;
> >>>>>>>> enum ipfix_proto_l2 l2;
> >>>>>>>> enum ipfix_proto_l3 l3;
> >>>>>>>> enum ipfix_proto_l4 l4;
> >>>>>>>> enum ipfix_proto_tunnel tunnel;
> >>>>>>>> + enum ipfix_flow_direction flow_direction;
> >>>>>>>>
> >>>>>>>> ipfix_init_template_msg(export_time_sec, exporter->seq_number,
> >>>>>>>> obs_domain_id, IPFIX_SET_ID_TEMPLATE, &msg,
> >>>>>>>> @@ -1559,41 +1641,44 @@ ipfix_send_template_msgs(struct
> >>>>>>>> dpif_ipfix_exporter *exporter,
> >>>>>>>> continue;
> >>>>>>>> }
> >>>>>>>> for (tunnel = 0; tunnel < NUM_IPFIX_PROTO_TUNNEL; tunnel++) {
> >>>>>>>> - /* When the size of the template packet reaches
> >>>>>>>> - * MAX_MESSAGE_LEN(1024), send it out.
> >>>>>>>> - * And then reinitialize the msg to construct a new
> >>>>>>>> - * packet for the following templates.
> >>>>>>>> - */
> >>>>>>>> - if (dp_packet_size(&msg) >= MAX_MESSAGE_LEN) {
> >>>>>>>> - /* Send template message. */
> >>>>>>>> - error_pkts = ipfix_send_template_msg(exporter->collectors,
> >>>>>>>> - &msg, set_hdr_offset);
> >>>>>>>> - tx_errors += error_pkts;
> >>>>>>>> - tx_packets += collectors_count(exporter->collectors) - error_pkts;
> >>>>>>>> -
> >>>>>>>> - /* Reinitialize the template msg. */
> >>>>>>>> - ipfix_init_template_msg(export_time_sec,
> >>>>>>>> - exporter->seq_number,
> >>>>>>>> - obs_domain_id,
> >>>>>>>> - IPFIX_SET_ID_TEMPLATE,
> >>>>>>>> - &msg,
> >>>>>>>> - &set_hdr_offset);
> >>>>>>>> + for (flow_direction = 0;
> >>>>>>>> + flow_direction < NUM_IPFIX_FLOW_DIRECTION;
> >>>>>>>> + flow_direction++) {
> >>>>>>>> + /* When the size of the template packet reaches
> >>>>>>>> + * MAX_MESSAGE_LEN(1024), send it out.
> >>>>>>>> + * And then reinitialize the msg to construct a new
> >>>>>>>> + * packet for the following templates.
> >>>>>>>> + */
> >>>>>>>> + if (dp_packet_size(&msg) >= MAX_MESSAGE_LEN) {
> >>>>>>>> + /* Send template message. */
> >>>>>>>> + error_pkts =
> >>>>>>>> + ipfix_send_template_msg(exporter->collectors,
> >>>>>>>> + &msg, set_hdr_offset);
> >>>>>>>> + tx_errors += error_pkts;
> >>>>>>>> + tx_packets +=
> >>>>>>>> + collectors_count(exporter->collectors)
> >>>>>>>> + - error_pkts;
> >>>>>>>> +
> >>>>>>>> + /* Reinitialize the template msg. */
> >>>>>>>> + ipfix_init_template_msg(export_time_sec,
> >>>>>>>> + exporter->seq_number,
> >>>>>>>> + obs_domain_id,
> >>>>>>>> + IPFIX_SET_ID_TEMPLATE,
> >>>>>>>> + &msg, &set_hdr_offset);
> >>>>>>>> + }
> >>>>>>>> +
> >>>>>>>> + ipfix_add_template_record(l2, l3, l4, tunnel,
> >>>>>>>> + flow_direction,
> >>>>>>>> + exporter->virtual_obs_id != NULL, &msg);
> >>>>>>>> }
> >>>>>>>> -
> >>>>>>>> - tmpl_hdr_offset = dp_packet_size(&msg);
> >>>>>>>> - tmpl_hdr = dp_packet_put_zeros(&msg, sizeof *tmpl_hdr);
> >>>>>>>> - tmpl_hdr->template_id = htons(
> >>>>>>>> - ipfix_get_template_id(l2, l3, l4, tunnel));
> >>>>>>>> - ipfix_define_template_fields(
> >>>>>>>> - l2, l3, l4, tunnel, exporter->virtual_obs_id != NULL,
> >>>>>>>> - tmpl_hdr_offset, &msg);
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> /* Send template message. */
> >>>>>>>> - error_pkts = ipfix_send_template_msg(exporter->collectors, &msg,
> >>>>>>>> set_hdr_offset);
> >>>>>>>> + error_pkts = ipfix_send_template_msg(exporter->collectors, &msg,
> >>>>>>>> + set_hdr_offset);
> >>>>>>>> tx_errors += error_pkts;
> >>>>>>>> tx_packets += collectors_count(exporter->collectors) - error_pkts;
> >>>>>>>>
> >>>>>>>> @@ -1878,8 +1963,80 @@ ipfix_cache_update(struct dpif_ipfix_exporter
> >>>>>>>> *exporter,
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> +static void
> >>>>>>>> +ipfix_destroy_iface_data_record(struct ipfix_data_record_flow_key_iface
> >>>>>>>> *data)
> >>>>>>>> +{
> >>>>>>>> + free(data->if_descr);
> >>>>>>>> + free(data->if_name);
> >>>>>>>> +}
> >>>>>>>> +
> >>>>>>>> +/* Fills '*data' structure based on port number 'port_no'. Caller must destroy
> >>>>>>>> + * 'data' with ipfix_destroy_iface_data_record(). */
> >>>>>>>> +static int
> >>>>>>>> +ipfix_get_iface_data_record(const struct dpif_ipfix *di, odp_port_t port_no,
> >>>>>>>> + struct ipfix_data_record_flow_key_iface *data)
> >>>>>>>> + OVS_REQUIRES(mutex)
> >>>>>>>> +{
> >>>>>>>> + struct dpif_ipfix_port *port;
> >>>>>>>> + struct smap netdev_status;
> >>>>>>>> +
> >>>>>>>> + port = dpif_ipfix_find_port(di, port_no);
> >>>>>>>> + if (!port) {
> >>>>>>>> + *data = (struct ipfix_data_record_flow_key_iface) {0};
> >>>>>>>> + return -1;
> >>>>>>>> + }
> >>>>>>>> +
> >>>>>>>> + smap_init(&netdev_status);
> >>>>>>>> + if (!netdev_get_status(port->ofport->netdev, &netdev_status)) {
> >>>>>>>> + data->if_type = htonl(smap_get_ullong(&netdev_status, "if_type", 0));
> >>>>>>>> + data->if_descr = nullable_xstrdup(smap_get(&netdev_status,
> >>>>>>>> + "if_descr"));
> >>>>>>>> + } else {
> >>>>>>>> + data->if_type = 0;
> >>>>>>>> + data->if_descr = NULL;
> >>>>>>>> + }
> >>>>>>>> +
> >>>>>>>> + smap_destroy(&netdev_status);
> >>>>>>>> + data->if_index = htonl(port->ifindex);
> >>>>>>>> + data->if_descr_len = data->if_descr ? strlen(data->if_descr) : 0;
> >>>>>>>> + data->if_name = nullable_xstrdup(netdev_get_name(port->ofport-
> >>>>>>>>> netdev));
> >>>>>>>> + data->if_name_len = data->if_name ? strlen(data->if_name) : 0;
> >>>>>>>> +
> >>>>>>>> + return 0;
> >>>>>>>> +}
> >>>>>>>> +
> >>>>>>>> +static void
> >>>>>>>> +ipfix_put_iface_data_record(const struct dpif_ipfix *di, odp_port_t port_no,
> >>>>>>>> + struct dp_packet *msg)
> >>>>>>>> + OVS_REQUIRES(mutex)
> >>>>>>>> +{
> >>>>>>>> + struct ipfix_data_record_flow_key_iface data;
> >>>>>>>> + int err;
> >>>>>>>> +
> >>>>>>>> + err = ipfix_get_iface_data_record(di, port_no, &data);
> >>>>>>>> + if (err == 0) {
> >>>>>>>> + dp_packet_put(msg, &data.if_index, sizeof data.if_index);
> >>>>>>>> + dp_packet_put(msg, &data.if_type, sizeof data.if_type);
> >>>>>>>> + dp_packet_put(msg, &data.if_name_len, sizeof data.if_name_len);
> >>>>>>>> + if (data.if_name_len) {
> >>>>>>>> + dp_packet_put(msg, data.if_name, data.if_name_len);
> >>>>>>>> + }
> >>>>>>>> + dp_packet_put(msg, &data.if_descr_len, sizeof data.if_descr_len);
> >>>>>>>> + if (data.if_descr_len) {
> >>>>>>>> + dp_packet_put(msg, data.if_descr, data.if_descr_len);
> >>>>>>>> + }
> >>>>>>>> + ipfix_destroy_iface_data_record(&data);
> >>>>>>>> + } else {
> >>>>>>>> + dp_packet_put_zeros(msg, sizeof data.if_index);
> >>>>>>>> + dp_packet_put_zeros(msg, sizeof data.if_type);
> >>>>>>>> + dp_packet_put_zeros(msg, sizeof data.if_name_len);
> >>>>>>>> + dp_packet_put_zeros(msg, sizeof data.if_descr_len);
> >>>>>>>> + }
> >>>>>>>> +}
> >>>>>>>> +
> >>>>>>>> static enum ipfix_sampled_packet_type
> >>>>>>>> -ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry,
> >>>>>>>> +ipfix_cache_entry_init(const struct dpif_ipfix *di,
> >>>>>>>> + struct ipfix_flow_cache_entry *entry,
> >>>>>>>> const struct dp_packet *packet, const struct flow *flow,
> >>>>>>>> uint64_t packet_delta_count, uint32_t obs_domain_id,
> >>>>>>>> uint32_t obs_point_id, odp_port_t output_odp_port,
> >>>>>>>> @@ -1887,6 +2044,7 @@ ipfix_cache_entry_init(struct ipfix_flow_cache_entry
> >>>>>>>> *entry,
> >>>>>>>> const struct dpif_ipfix_port *tunnel_port,
> >>>>>>>> const struct flow_tnl *tunnel_key,
> >>>>>>>> struct dpif_ipfix_global_stats *stats)
> >>>>>>>> + OVS_REQUIRES(mutex)
> >>>>>>>> {
> >>>>>>>> struct ipfix_flow_key *flow_key;
> >>>>>>>> struct dp_packet msg;
> >>>>>>>> @@ -1961,8 +2119,14 @@ ipfix_cache_entry_init(struct
> >>>>>>> ipfix_flow_cache_entry
> >>>>>>>> *entry,
> >>>>>>>> tunnel = IPFIX_PROTO_TUNNELED;
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> + uint8_t flow_direction =
> >>>>>>>> + (direction == NX_ACTION_SAMPLE_INGRESS ? INGRESS_FLOW
> >>>>>>>> + : direction == NX_ACTION_SAMPLE_EGRESS ? EGRESS_FLOW
> >>>>>>>> + : output_odp_port == ODPP_NONE ? INGRESS_FLOW : EGRESS_FLOW);
> >>>>>>>> +
> >>>>>>>> flow_key->obs_domain_id = obs_domain_id;
> >>>>>>>> - flow_key->template_id = ipfix_get_template_id(l2, l3, l4, tunnel);
> >>>>>>>> + flow_key->template_id = ipfix_get_template_id(l2, l3, l4, tunnel,
> >>>>>>>> + flow_direction);
> >>>>>>>>
> >>>>>>>> /* The fields defined in the ipfix_data_record_* structs and sent
> >>>>>>>> * below must match exactly the templates defined in
> >>>>>>>> @@ -1972,11 +2136,6 @@ ipfix_cache_entry_init(struct
> >>>>>>> ipfix_flow_cache_entry
> >>>>>>>> *entry,
> >>>>>>>> ? VLAN_ETH_HEADER_LEN : ETH_HEADER_LEN;
> >>>>>>>> ethernet_total_length = dp_packet_size(packet);
> >>>>>>>>
> >>>>>>>> - uint8_t flow_direction =
> >>>>>>>> - (direction == NX_ACTION_SAMPLE_INGRESS ? INGRESS_FLOW
> >>>>>>>> - : direction == NX_ACTION_SAMPLE_EGRESS ? EGRESS_FLOW
> >>>>>>>> - : output_odp_port == ODPP_NONE ? INGRESS_FLOW : EGRESS_FLOW);
> >>>>>>>> -
> >>>>>>>> /* Common Ethernet entities. */
> >>>>>>>> {
> >>>>>>>> struct ipfix_data_record_flow_key_common *data_common;
> >>>>>>>> @@ -1990,6 +2149,13 @@ ipfix_cache_entry_init(struct
> >>>>>>> ipfix_flow_cache_entry
> >>>>>>>> *entry,
> >>>>>>>> data_common->ethernet_header_length = ethernet_header_length;
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> + /* Interface Information Elements */
> >>>>>>>> + ipfix_put_iface_data_record(di, flow->in_port.odp_port, &msg);
> >>>>>>>> +
> >>>>>>>> + if (flow_direction == EGRESS_FLOW) {
> >>>>>>>> + ipfix_put_iface_data_record(di, output_odp_port, &msg);
> >>>>>>>> + }
> >>>>>>>> +
> >>>>>>>> if (l2 == IPFIX_PROTO_L2_VLAN) {
> >>>>>>>> struct ipfix_data_record_flow_key_vlan *data_vlan;
> >>>>>>>> uint16_t vlan_id = vlan_tci_to_vid(flow->vlans[0].tci);
> >>>>>>>> @@ -2414,13 +2580,15 @@ ipfix_send_data_msg(struct dpif_ipfix_exporter
> >>>>>>>> *exporter,
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> static void
> >>>>>>>> -dpif_ipfix_sample(struct dpif_ipfix_exporter *exporter,
> >>>>>>>> +dpif_ipfix_sample(const struct dpif_ipfix *di,
> >>>>>>>> + struct dpif_ipfix_exporter *exporter,
> >>>>>>>> const struct dp_packet *packet, const struct flow *flow,
> >>>>>>>> uint64_t packet_delta_count, uint32_t obs_domain_id,
> >>>>>>>> uint32_t obs_point_id, odp_port_t output_odp_port,
> >>>>>>>> enum nx_action_sample_direction direction,
> >>>>>>>> const struct dpif_ipfix_port *tunnel_port,
> >>>>>>>> const struct flow_tnl *tunnel_key)
> >>>>>>>> + OVS_REQUIRES(mutex)
> >>>>>>>> {
> >>>>>>>> struct ipfix_flow_cache_entry *entry;
> >>>>>>>> enum ipfix_sampled_packet_type sampled_packet_type;
> >>>>>>>> @@ -2428,7 +2596,7 @@ dpif_ipfix_sample(struct dpif_ipfix_exporter
> >>>>>>>> *exporter,
> >>>>>>>> /* Create a flow cache entry from the sample. */
> >>>>>>>> entry = xmalloc(sizeof *entry);
> >>>>>>>> sampled_packet_type =
> >>>>>>>> - ipfix_cache_entry_init(entry, packet,
> >>>>>>>> + ipfix_cache_entry_init(di, entry, packet,
> >>>>>>>> flow, packet_delta_count,
> >>>>>>>> obs_domain_id, obs_point_id,
> >>>>>>>> output_odp_port, direction,
> >>>>>>>> @@ -2484,16 +2652,16 @@ dpif_ipfix_bridge_sample(struct dpif_ipfix *di,
> >>>>>>> const
> >>>>>>>> struct dp_packet *packet,
> >>>>>>>> if (output_odp_port == ODPP_NONE && flow->tunnel.ip_dst) {
> >>>>>>>> /* Input tunnel. */
> >>>>>>>> tunnel_key = &flow->tunnel;
> >>>>>>>> - tunnel_port = dpif_ipfix_find_port(di, input_odp_port);
> >>>>>>>> + tunnel_port = dpif_ipfix_find_tunnel_port(di, input_odp_port);
> >>>>>>>> }
> >>>>>>>> if (output_odp_port != ODPP_NONE && output_tunnel_key) {
> >>>>>>>> /* Output tunnel, output_tunnel_key must be valid. */
> >>>>>>>> tunnel_key = output_tunnel_key;
> >>>>>>>> - tunnel_port = dpif_ipfix_find_port(di, output_odp_port);
> >>>>>>>> + tunnel_port = dpif_ipfix_find_tunnel_port(di, output_odp_port);
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> - dpif_ipfix_sample(&di->bridge_exporter.exporter, packet, flow,
> >>>>>>>> + dpif_ipfix_sample(di, &di->bridge_exporter.exporter, packet, flow,
> >>>>>>>> packet_delta_count,
> >>>>>>>> di->bridge_exporter.options->obs_domain_id,
> >>>>>>>> di->bridge_exporter.options->obs_point_id,
> >>>>>>>> @@ -2528,16 +2696,16 @@ dpif_ipfix_flow_sample(struct dpif_ipfix *di, const
> >>>>>>>> struct dp_packet *packet,
> >>>>>>>> if (output_odp_port == ODPP_NONE && flow->tunnel.ip_dst) {
> >>>>>>>> /* Input tunnel. */
> >>>>>>>> tunnel_key = &flow->tunnel;
> >>>>>>>> - tunnel_port = dpif_ipfix_find_port(di, input_odp_port);
> >>>>>>>> + tunnel_port = dpif_ipfix_find_tunnel_port(di, input_odp_port);
> >>>>>>>> }
> >>>>>>>> if (output_odp_port != ODPP_NONE && output_tunnel_key) {
> >>>>>>>> /* Output tunnel, output_tunnel_key must be valid. */
> >>>>>>>> tunnel_key = output_tunnel_key;
> >>>>>>>> - tunnel_port = dpif_ipfix_find_port(di, output_odp_port);
> >>>>>>>> + tunnel_port = dpif_ipfix_find_tunnel_port(di, output_odp_port);
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> - dpif_ipfix_sample(&node->exporter.exporter, packet, flow,
> >>>>>>>> + dpif_ipfix_sample(di, &node->exporter.exporter, packet, flow,
> >>>>>>>> packet_delta_count,
> >>>>>>>> cookie->flow_sample.obs_domain_id,
> >>>>>>>> cookie->flow_sample.obs_point_id,
> >>>>>>>> diff --git a/ofproto/ofproto-dpif-ipfix.h b/ofproto/ofproto-dpif-ipfix.h
> >>>>>>>> index 0808ede..0b21441 100644
> >>>>>>>> --- a/ofproto/ofproto-dpif-ipfix.h
> >>>>>>>> +++ b/ofproto/ofproto-dpif-ipfix.h
> >>>>>>>> @@ -33,8 +33,8 @@ struct dpif_ipfix *dpif_ipfix_create(void);
> >>>>>>>> struct dpif_ipfix *dpif_ipfix_ref(const struct dpif_ipfix *);
> >>>>>>>> void dpif_ipfix_unref(struct dpif_ipfix *);
> >>>>>>>>
> >>>>>>>> -void dpif_ipfix_add_tunnel_port(struct dpif_ipfix *, struct ofport *,
> >>>>>>>> odp_port_t);
> >>>>>>>> -void dpif_ipfix_del_tunnel_port(struct dpif_ipfix *, odp_port_t);
> >>>>>>>> +void dpif_ipfix_add_port(struct dpif_ipfix *, struct ofport *, odp_port_t);
> >>>>>>>> +void dpif_ipfix_del_port(struct dpif_ipfix *, odp_port_t);
> >>>>>>>>
> >>>>>>>> uint32_t dpif_ipfix_get_bridge_exporter_probability(const struct dpif_ipfix *);
> >>>>>>>> bool dpif_ipfix_get_bridge_exporter_tunnel_sampling(const struct dpif_ipfix
> >>>>>>> *);
> >>>>>>>> @@ -42,7 +42,7 @@ bool
> >>>>>>> dpif_ipfix_get_bridge_exporter_input_sampling(const
> >>>>>>>> struct dpif_ipfix *);
> >>>>>>>> bool dpif_ipfix_get_bridge_exporter_output_sampling(const struct dpif_ipfix
> >>>>>>>> *);
> >>>>>>>> bool dpif_ipfix_get_flow_exporter_tunnel_sampling(const struct dpif_ipfix *,
> >>>>>>>> const uint32_t);
> >>>>>>>> -bool dpif_ipfix_get_tunnel_port(const struct dpif_ipfix *, odp_port_t);
> >>>>>>>> +bool dpif_ipfix_is_tunnel_port(const struct dpif_ipfix *, odp_port_t);
> >>>>>>>> void dpif_ipfix_set_options(
> >>>>>>>> struct dpif_ipfix *,
> >>>>>>>> const struct ofproto_ipfix_bridge_exporter_options *,
> >>>>>>>> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> >>>>>>>> index 7f7adb2..3a37559 100644
> >>>>>>>> --- a/ofproto/ofproto-dpif-xlate.c
> >>>>>>>> +++ b/ofproto/ofproto-dpif-xlate.c
> >>>>>>>> @@ -2946,7 +2946,7 @@ compose_ipfix_action(struct xlate_ctx *ctx,
> >>>>>>> odp_port_t
> >>>>>>>> output_odp_port)
> >>>>>>>> * OVS_USERSPACE_ATTR_TUNNEL_OUT_PORT
> >>>>>>>> */
> >>>>>>>> if (dpif_ipfix_get_bridge_exporter_tunnel_sampling(ipfix) &&
> >>>>>>>> - dpif_ipfix_get_tunnel_port(ipfix, output_odp_port) ) {
> >>>>>>>> + dpif_ipfix_is_tunnel_port(ipfix, output_odp_port) ) {
> >>>>>>>> tunnel_out_port = output_odp_port;
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>> @@ -5199,7 +5199,7 @@ xlate_sample_action(struct xlate_ctx *ctx,
> >>>>>>>>
> >>>>>>>> if (dpif_ipfix_get_flow_exporter_tunnel_sampling(ipfix,
> >>>>>>>> os->collector_set_id)
> >>>>>>>> - && dpif_ipfix_get_tunnel_port(ipfix, output_odp_port)) {
> >>>>>>>> + && dpif_ipfix_is_tunnel_port(ipfix, output_odp_port)) {
> >>>>>>>> tunnel_out_port = output_odp_port;
> >>>>>>>> emit_set_tunnel = true;
> >>>>>>>> }
> >>>>>>>> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> >>>>>>>> index 50f440f..72a4334 100644
> >>>>>>>> --- a/ofproto/ofproto-dpif.c
> >>>>>>>> +++ b/ofproto/ofproto-dpif.c
> >>>>>>>> @@ -1865,9 +1865,6 @@ port_construct(struct ofport *port_)
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> port->is_tunnel = true;
> >>>>>>>> - if (ofproto->ipfix) {
> >>>>>>>> - dpif_ipfix_add_tunnel_port(ofproto->ipfix, port_, port->odp_port);
> >>>>>>>> - }
> >>>>>>>> } else {
> >>>>>>>> /* Sanity-check that a mapping doesn't already exist. This
> >>>>>>>> * shouldn't happen for non-tunnel ports. */
> >>>>>>>> @@ -1888,6 +1885,9 @@ port_construct(struct ofport *port_)
> >>>>>>>> if (ofproto->sflow) {
> >>>>>>>> dpif_sflow_add_port(ofproto->sflow, port_, port->odp_port);
> >>>>>>>> }
> >>>>>>>> + if (ofproto->ipfix) {
> >>>>>>>> + dpif_ipfix_add_port(ofproto->ipfix, port_, port->odp_port);
> >>>>>>>> + }
> >>>>>>>>
> >>>>>>>> return 0;
> >>>>>>>> }
> >>>>>>>> @@ -1933,10 +1933,6 @@ port_destruct(struct ofport *port_, bool del)
> >>>>>>>> atomic_count_dec(&ofproto->backer->tnl_count);
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> - if (port->is_tunnel && ofproto->ipfix) {
> >>>>>>>> - dpif_ipfix_del_tunnel_port(ofproto->ipfix, port->odp_port);
> >>>>>>>> - }
> >>>>>>>> -
> >>>>>>>> tnl_port_del(port);
> >>>>>>>> sset_find_and_delete(&ofproto->ports, devname);
> >>>>>>>> sset_find_and_delete(&ofproto->ghost_ports, devname);
> >>>>>>>> @@ -1951,6 +1947,9 @@ port_destruct(struct ofport *port_, bool del)
> >>>>>>>> if (ofproto->sflow) {
> >>>>>>>> dpif_sflow_del_port(ofproto->sflow, port->odp_port);
> >>>>>>>> }
> >>>>>>>> + if (ofproto->ipfix) {
> >>>>>>>> + dpif_ipfix_del_port(ofproto->ipfix, port->odp_port);
> >>>>>>>> + }
> >>>>>>>>
> >>>>>>>> free(port->qdscp);
> >>>>>>>> }
> >>>>>>>> @@ -2076,13 +2075,11 @@ set_ipfix(
> >>>>>>>> di, bridge_exporter_options, flow_exporters_options,
> >>>>>>>> n_flow_exporters_options);
> >>>>>>>>
> >>>>>>>> - /* Add tunnel ports only when a new ipfix created */
> >>>>>>>> + /* Add ports only when a new ipfix created */
> >>>>>>>> if (new_di == true) {
> >>>>>>>> struct ofport_dpif *ofport;
> >>>>>>>> HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
> >>>>>>>> - if (ofport->is_tunnel == true) {
> >>>>>>>> - dpif_ipfix_add_tunnel_port(di, &ofport->up, ofport->odp_port);
> >>>>>>>> - }
> >>>>>>>> + dpif_ipfix_add_port(di, &ofport->up, ofport->odp_port);
> >>>>>>>> }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> --
> >>>>>>>> 1.8.3.1
> >>>>>>>
> >>>>>>> --------------------------------------------------------------
> >>>>>>> Intel Research and Development Ireland Limited
> >>>>>>> Registered in Ireland
> >>>>>>> Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
> >>>>>>> Registered Number: 308263
> >>>>>>>
> >>>>>>>
> >>>>>>> This e-mail and any attachments may contain confidential material for the sole
> >>>>>>> use of the intended recipient(s). Any review or distribution by others is
> >>>>>>> strictly prohibited. If you are not the intended recipient, please contact the
> >>>>>>> sender and delete all copies.
> >>>>>>>
> >>>>>>> _______________________________________________
> >>>>>>> dev mailing list
> >>>>>>> dev at openvswitch.org
> >>>>>>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
> >>>>>> --------------------------------------------------------------
> >>>>>> Intel Research and Development Ireland Limited
> >>>>>> Registered in Ireland
> >>>>>> Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
> >>>>>> Registered Number: 308263
> >>>>>>
> >>>>>>
> >>>>>> This e-mail and any attachments may contain confidential material for the sole
> >>>>>> use of the intended recipient(s). Any review or distribution by others is
> >>>>>> strictly prohibited. If you are not the intended recipient, please contact the
> >>>>>> sender and delete all copies.
> >>>>>>
> >>>>>> _______________________________________________
> >>>>>> dev mailing list
> >>>>>> dev at openvswitch.org
> >>>>>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
> >>>>>>
> >>>>>
> >>>>> _______________________________________________
> >>>>> dev mailing list
> >>>>> dev at openvswitch.org
> >>>>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
> >>
>
More information about the dev
mailing list