I've figured out the mac issue,
Using the  _fmt_str = '!HIIIH16s6B24sQ6x' and byte array for mac
although the pdp_start_epoch is still way off for some reason, any ideas?
Thanks, Nick

On Fri, Jun 19, 2020 at 3:42 PM Nick <urchen...@gmail.com> wrote:

> Hi,
>
> I'm trying to modify the NXActionSample2 action and wanted to ask for your
> help. Basically I have an OVS patch that modifies the Sampling action and
> adds a few custom fields. I currently use it with ovs-ofctl, but It would
> be great if I can just modify Ryu to accept the new args.
>
> I've initially posted this question on this github issue
> https://github.com/faucetsdn/ryu/issues/104, it's easier to read there
> due to code blocks.
>
> Here is my ovs-ofctl
> ```
> sudo ovs-ofctl add-flow cwag_br0
> "table=15,priority=12,metadata=0x75945885e85,actions=sample(probability=600,collector_set_id=1,obs_domain_id=1,obs_point_id=1,apn_mac_addr=58:bc:27:13:31:50,msisdn=5101006096,apn_name=\"cwc
> wifi offload\",pdp_start_epoch=100,sampling_port=gre0),resubmit(,20)"
> ```
>
> Here is the corresponding OVS flow it creates
> ```
>  cookie=0x0, duration=33.792s, table=15, n_packets=0, n_bytes=0,
> priority=12,metadata=0x75945885e85
> actions=sample(probability=600,collector_set_id=1,obs_domain_id=1,obs_point_id=1,pdp_start_epoch=100,apn_mac_addr=58:bc:27:13:31:50,msisdn=5101006096,apn_name="cwc
> wifi offload",sampling_port=gre0),resubmit(,20)
> ```
>
> The added fields from the standard Sample action are:
> ```
> msisdn:
> apn_mac_addr
> apn_name
> pdp_start_epoch
> ```
> Here is the struct in ovs:
> ```
> struct nx_action_sample2 {
>     ovs_be16 type;                  /* OFPAT_VENDOR. */
>     ovs_be16 len;                   /* Length is 32. */
>     ovs_be32 vendor;                /* NX_VENDOR_ID. */
>     ovs_be16 subtype;               /* NXAST_SAMPLE. */
>     ovs_be16 probability;           /* Fraction of packets to sample. */
>     ovs_be32 collector_set_id;      /* ID of collector set in OVSDB. */
>     ovs_be32 obs_domain_id;         /* ID of sampling observation domain.
> */
>     ovs_be32 obs_point_id;          /* ID of sampling observation point. */
>     ovs_be16 sampling_port;         /* Sampling port. */
>     uint8_t  msisdn[16];
>     struct   eth_addr apn_mac_addr;
>     uint8_t  apn_name[24];
>     uint64_t pdp_start_epoch;
>     uint8_t  direction;             /* NXAST_SAMPLE3 only. */
>     uint8_t  zeros[5];              /* Pad to a multiple of 8 bytes */
>  };
>  OFP_ASSERT(sizeof(struct nx_action_sample2) == 88);
>
> /* not sure if this is requried */
> struct ofpact_sample {
>     OFPACT_PADDED_MEMBERS(
>         struct ofpact ofpact;
>         uint16_t probability;   /* Always positive. */
>         uint32_t collector_set_id;
>         uint32_t obs_domain_id;
>         uint32_t obs_point_id;
>         ofp_port_t sampling_port;
>         enum nx_action_sample_direction direction;
>         uint8_t msisdn[16];
>         struct eth_addr apn_mac_addr;
>         uint8_t apn_name[24];
>         uint64_t pdp_start_epoch;
>     );
> };
> ```
>
> Currently with some hacking I've achieved this with RYU:
>
> ```
> parser.NXActionSample2(
>             probability=self.ipfix_config.probability,
> collector_set_id=self.ipfix_config.collector_set_id,
>             obs_domain_id=self.ipfix_config.obs_domain_id,
> obs_point_id=self.ipfix_config.obs_point_id,
>             apn_mac_addr="0a0027000005",
>             msisdn="5101006096", apn_name="cwc wifi offload",
> pdp_start_epoch=100,
>             sampling_port=32768,
>             )
>
>  cookie=0x0, duration=11.112s, table=203, n_packets=0, n_bytes=0,
> priority=12
> actions=sample(probability=65535,collector_set_id=1,obs_domain_id=1,obs_point_id=1,pdp_start_epoch=7205759403792793600,apn_mac_addr=30:61:30:30:32:37,msisdn=5101006096,apn_name="cwc
> wifi
> offload",sampling_port=gre0),resubmit(,16),set_field:0->reg0,set_field:0->reg3
> ```
> All the fields are correct except the `pdp_start_epoch` and
> `apn_mac_addr`. I assume its because I messed up the struct packing as I'm
> not sure how to properly pack/encode the mac addr. Here is the relevant RYU
> code ( I've tried using `ofp.oxm_from_user_header,
> ofp.oxm_serialize_header` functions but didn't get anywhere so just
> encoding to ascii worked best for me.
>
> ```
>
>     class NXActionSample2(NXAction):
>
>         _subtype = nicira_ext.NXAST_SAMPLE2
>
>         # probability, collector_set_id, obs_domain_id,
>         # obs_point_id, msisdn, apn_mac_addr, apn_name, sampling_port
>         _fmt_str = '!HIIIH16s6s24sQ6x'
>
>         def __init__(self,
>                      probability,
>                      msisdn,
>                      apn_mac_addr,
>                      apn_name,
>                      pdp_start_epoch,
>                      collector_set_id=0,
>                      obs_domain_id=0,
>                      obs_point_id=0,
>                      sampling_port=0,
>                      type_=None, len_=None, experimenter=None,
> subtype=None):
>             super(NXActionSample2, self).__init__()
>             self.probability = probability
>             self.collector_set_id = collector_set_id
>             self.obs_domain_id = obs_domain_id
>             self.obs_point_id = obs_point_id
>
>             self.msisdn = msisdn.encode('ascii')
>             self.apn_mac_addr = apn_mac_addr.encode('ascii')
>             self.apn_name = apn_name.encode('ascii')
>             self.pdp_start_epoch = pdp_start_epoch
>
>             self.sampling_port = sampling_port
>
>         @classmethod
>         def parser(cls, buf):
>             (probability,
>              collector_set_id,
>              obs_domain_id,
>              obs_point_id,
>              sampling_port,
>              msisdn,
>              apn_mac_addr,
>              apn_name,
>              pdp_start_epoch) = struct.unpack_from(
>                 cls._fmt_str, buf, 0)
>
>             return cls(probability,
>                        msisdn,
>                        apn_mac_addr,
>                        apn_name,
>                        pdp_start_epoch,
>                        collector_set_id,
>                        obs_domain_id,
>                        obs_point_id,
>                        sampling_port)
>
>         def serialize_body(self):
>             data = bytearray()
>             msg_pack_into(self._fmt_str, data, 0,
>                           self.probability,
>                           self.collector_set_id,
>                           self.obs_domain_id,
>                           self.obs_point_id,
>                           self.sampling_port,
>                           self.msisdn,
>                           self.apn_mac_addr,
>                           self.apn_name,
>                           self.pdp_start_epoch)
>             return data
>
> ```
>
> Would really appreciate your help, thank you!
>
> Thanks,
> Nick
>
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to