diff --git a/ryu/ofproto/nx_match.py b/ryu/ofproto/nx_match.py index a3a58cbb..02fa0007 100644 --- a/ryu/ofproto/nx_match.py +++ b/ryu/ofproto/nx_match.py @@ -44,6 +44,10 @@ FWW_IPV6_LABEL = 1 << 7 FWW_NW_TTL = 1 << 8 FWW_ALL = (1 << 13) - 1 +FLOW_NW_FRAG_ANY = 1 << 0 +FLOW_NW_FRAG_LATER = 1 << 1 +FLOW_NW_FRAG_MASK = FLOW_NW_FRAG_ANY | FLOW_NW_FRAG_LATER + # Ethernet types, for set_dl_type() ETH_TYPE_IP = 0x0800 ETH_TYPE_ARP = 0x0806 @@ -88,6 +92,7 @@ class Flow(object): self.ipv6_src = [] self.ipv6_dst = [] self.nd_target = [] + self.nw_frag = 0 self.ipv6_label = 0 @@ -106,6 +111,7 @@ class FlowWildcards(object): self.ipv6_src_mask = [] self.ipv6_dst_mask = [] self.nd_target_mask = [] + self.nw_frag_mask = 0 self.wildcards = FWW_ALL @@ -203,6 +209,14 @@ class ClsRule(object): self.wc.wildcards &= ~FWW_NW_TTL self.flow.nw_ttl = nw_ttl + def set_nw_frag(self, nw_frag): + self.wc.nw_frag_mask |= FLOW_NW_FRAG_MASK + self.flow.nw_frag = nw_frag + + def set_nw_frag_masked(self, nw_frag, mask): + self.wc.nw_frag_mask = mask + self.flow.nw_frag = nw_frag & mask + def set_arp_spa(self, spa): self.set_arp_spa_masked(spa, UINT32_MAX) @@ -235,6 +249,10 @@ class ClsRule(object): self.wc.wildcards &= ~FWW_IPV6_LABEL self.flow.ipv6_label = label + def set_ipv6_label(self, label): + self.wc.wildcards &= ~FWW_IPV6_LABEL + self.flow.ipv6_label = label + def set_ipv6_src_masked(self, src, mask): self.wc.ipv6_src_mask = mask self.flow.ipv6_src = [x & y for (x, y) in itertools.izip(src, mask)] @@ -589,6 +607,22 @@ class MFNdTarget(MFField): rule.wc.nd_target_mask) +@_register_make +@_set_nxm_headers([ofproto_v1_0.NXM_NX_IP_FRAG, + ofproto_v1_0.NXM_NX_IP_FRAG_W]) +class MFIpFrag(MFField): + @classmethod + def make(cls): + return cls('!B') + + def put(self, buf, offset, rule): + if rule.wc.nw_frag_mask == FLOW_NW_FRAG_MASK: + return self._put(buf, offset, rule.flow.nw_frag) + else: + return self.putw(buf, offset, rule.flow.nw_frag, + rule.wc.nw_frag_mask & FLOW_NW_FRAG_MASK) + + @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_ARP_THA]) class MFArpTha(MFField): @@ -805,6 +839,13 @@ def serialize_nxm_match(rule, buf, offset): if not rule.wc.wildcards & FWW_ARP_THA: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_ARP_THA, rule) + if rule.flow.nw_frag: + if rule.wc.nw_frag_mask == FLOW_NW_FRAG_MASK: + header = ofproto_v1_0.NXM_NX_IP_FRAG + else: + header = ofproto_v1_0.NXM_NX_IP_FRAG_W + offset += nxm_put(buf, offset, header, rule) + # Tunnel Id if rule.wc.tun_id_mask != 0: if rule.wc.tun_id_mask == UINT64_MAX: diff --git a/ryu/ofproto/ofproto_v1_0.py b/ryu/ofproto/ofproto_v1_0.py index 078178e0..ec37caf7 100644 --- a/ryu/ofproto/ofproto_v1_0.py +++ b/ryu/ofproto/ofproto_v1_0.py @@ -722,6 +722,9 @@ NXM_NX_ND_SLL = nxm_header(0x0001, 24, 6) NXM_NX_ND_TLL = nxm_header(0x0001, 25, 6) +NXM_NX_IP_FRAG = nxm_header(0x0001, 26, 1) +NXM_NX_IP_FRAG_W = nxm_header_w(0x0001, 26, 1) + NXM_NX_IPV6_LABEL = nxm_header(0x0001, 27, 4) NXM_NX_IP_ECN = nxm_header(0x0001, 28, 1)