def _make_exp_hdr(oxx, mod, n): exp_hdr = bytearray() try: get_desc = getattr(mod, '_' + oxx + '_field_desc') desc = get_desc(n) except KeyError: return n, exp_hdr if desc._class == OFPXXC_EXPERIMENTER: (exp_id, exp_type) = n assert desc.experimenter_id == exp_id oxx_type = getattr(desc, oxx + '_type') if desc.exp_type == 2560: # XXX # This block implements EXT-256 style experimenter OXM. exp_hdr_pack_str = '!IH' # experimenter_id, exp_type msg_pack_into(exp_hdr_pack_str, exp_hdr, 0, desc.experimenter_id, desc.exp_type) else: assert oxx_type == exp_type | (OFPXXC_EXPERIMENTER << 7) exp_hdr_pack_str = '!I' # experimenter_id msg_pack_into(exp_hdr_pack_str, exp_hdr, 0, desc.experimenter_id) assert len(exp_hdr) == struct.calcsize(exp_hdr_pack_str) n = oxx_type assert (n >> 7) == OFPXXC_EXPERIMENTER return n, exp_hdr
def serialize(self, payload=None, prev=None): present = 0 hdr = bytearray() optional = bytearray() if self.checksum is not None: present |= GRE_CHECKSUM_FLG # For purposes of computing the checksum, # the value of the checksum field is zero. # Also, because Reserved1 is always 0x00 of 2 bytes, # Set in conjunction with checksum. optional += b'\x00' * self._CHECKSUM_LEN if self._key is not None: present |= GRE_KEY_FLG optional += struct.pack(self._KEY_PACK_STR, self._key) if self.seq_number is not None: present |= GRE_SEQUENCE_NUM_FLG optional += struct.pack(self._SEQNUM_PACK_STR, self.seq_number) msg_pack_into(self._PACK_STR, hdr, 0, present, self.version, self.protocol) hdr += optional if self.checksum: self.checksum = packet_utils.checksum(hdr) struct.pack_into(self._CHECKSUM_PACK_STR, hdr, self._MIN_LEN, self.checksum) return hdr
def _serialize_header(oxx, mod, n, buf, offset): try: get_desc = getattr(mod, '_' + oxx + '_field_desc') desc = get_desc(n) value_len = desc.type.size except KeyError: value_len = 0 n, exp_hdr = _make_exp_hdr(oxx, mod, n) exp_hdr_len = len(exp_hdr) pack_str = "!I%ds" % (exp_hdr_len, ) msg_pack_into(pack_str, buf, offset, (n << 9) | (0 << 8) | (exp_hdr_len + value_len), bytes(exp_hdr)) return struct.calcsize(pack_str)
def _serialize(oxx, mod, n, value, mask, buf, offset): n, exp_hdr = _make_exp_hdr(oxx, mod, n) exp_hdr_len = len(exp_hdr) value_len = len(value) if mask: assert value_len == len(mask) pack_str = "!I%ds%ds%ds" % (exp_hdr_len, value_len, len(mask)) msg_pack_into(pack_str, buf, offset, (n << 9) | (1 << 8) | (exp_hdr_len + value_len * 2), bytes(exp_hdr), value, mask) else: pack_str = "!I%ds%ds" % ( exp_hdr_len, value_len, ) msg_pack_into(pack_str, buf, offset, (n << 9) | (0 << 8) | (exp_hdr_len + value_len), bytes(exp_hdr), value) return struct.calcsize(pack_str)
def serialize_nxm_match(rule, buf, offset): old_offset = offset if not rule.wc.wildcards & FWW_IN_PORT: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_IN_PORT, rule) # Ethernet. if rule.flow.dl_dst != mac.DONTCARE: if rule.wc.dl_dst_mask: header = ofproto_v1_0.NXM_OF_ETH_DST_W else: header = ofproto_v1_0.NXM_OF_ETH_DST offset += nxm_put(buf, offset, header, rule) if rule.flow.dl_src != mac.DONTCARE: if rule.wc.dl_src_mask: header = ofproto_v1_0.NXM_OF_ETH_SRC_W else: header = ofproto_v1_0.NXM_OF_ETH_SRC offset += nxm_put(buf, offset, header, rule) if not rule.wc.wildcards & FWW_DL_TYPE: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_ETH_TYPE, rule) # 802.1Q if rule.wc.vlan_tci_mask != 0: if rule.wc.vlan_tci_mask == UINT16_MAX: header = ofproto_v1_0.NXM_OF_VLAN_TCI else: header = ofproto_v1_0.NXM_OF_VLAN_TCI_W offset += nxm_put(buf, offset, header, rule) # L3 if not rule.wc.wildcards & FWW_NW_DSCP: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_IP_TOS, rule) if not rule.wc.wildcards & FWW_NW_ECN: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_IP_ECN, rule) if not rule.wc.wildcards & FWW_NW_TTL: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_IP_TTL, rule) if not rule.wc.wildcards & FWW_NW_PROTO: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_IP_PROTO, rule) if not rule.wc.wildcards & FWW_NW_PROTO and (rule.flow.nw_proto == inet.IPPROTO_ICMP): if rule.wc.tp_src_mask != 0: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_ICMP_TYPE, rule) if rule.wc.tp_dst_mask != 0: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_ICMP_CODE, rule) if rule.flow.tp_src != 0: if rule.flow.nw_proto == 6: if rule.wc.tp_src_mask == UINT16_MAX: header = ofproto_v1_0.NXM_OF_TCP_SRC else: header = ofproto_v1_0.NXM_OF_TCP_SRC_W elif rule.flow.nw_proto == 17: if rule.wc.tp_src_mask == UINT16_MAX: header = ofproto_v1_0.NXM_OF_UDP_SRC else: header = ofproto_v1_0.NXM_OF_UDP_SRC_W else: header = 0 if header != 0: offset += nxm_put(buf, offset, header, rule) if rule.flow.tp_dst != 0: if rule.flow.nw_proto == 6: if rule.wc.tp_dst_mask == UINT16_MAX: header = ofproto_v1_0.NXM_OF_TCP_DST else: header = ofproto_v1_0.NXM_OF_TCP_DST_W elif rule.flow.nw_proto == 17: if rule.wc.tp_dst_mask == UINT16_MAX: header = ofproto_v1_0.NXM_OF_UDP_DST else: header = ofproto_v1_0.NXM_OF_UDP_DST_W else: header = 0 if header != 0: offset += nxm_put(buf, offset, header, rule) if rule.flow.tcp_flags != 0: # TCP Flags can only be used if the ethernet type is IPv4 or IPv6 if rule.flow.dl_type in (ether.ETH_TYPE_IP, ether.ETH_TYPE_IPV6): # TCP Flags can only be used if the ip protocol is TCP if rule.flow.nw_proto == inet.IPPROTO_TCP: if rule.wc.tcp_flags_mask == UINT16_MAX: header = ofproto_v1_0.NXM_NX_TCP_FLAGS else: header = ofproto_v1_0.NXM_NX_TCP_FLAGS_W else: header = 0 else: header = 0 if header != 0: offset += nxm_put(buf, offset, header, rule) # IP Source and Destination if rule.flow.nw_src != 0: if rule.wc.nw_src_mask == UINT32_MAX: header = ofproto_v1_0.NXM_OF_IP_SRC else: header = ofproto_v1_0.NXM_OF_IP_SRC_W offset += nxm_put(buf, offset, header, rule) if rule.flow.nw_dst != 0: if rule.wc.nw_dst_mask == UINT32_MAX: header = ofproto_v1_0.NXM_OF_IP_DST else: header = ofproto_v1_0.NXM_OF_IP_DST_W offset += nxm_put(buf, offset, header, rule) # IPv6 if not rule.wc.wildcards & FWW_NW_PROTO and (rule.flow.nw_proto == inet.IPPROTO_ICMPV6): if rule.wc.tp_src_mask != 0: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_ICMPV6_TYPE, rule) if rule.wc.tp_dst_mask != 0: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_ICMPV6_CODE, rule) if not rule.wc.wildcards & FWW_IPV6_LABEL: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_IPV6_LABEL, rule) if len(rule.flow.ipv6_src): if len(rule.wc.ipv6_src_mask): header = ofproto_v1_0.NXM_NX_IPV6_SRC_W else: header = ofproto_v1_0.NXM_NX_IPV6_SRC offset += nxm_put(buf, offset, header, rule) if len(rule.flow.ipv6_dst): if len(rule.wc.ipv6_dst_mask): header = ofproto_v1_0.NXM_NX_IPV6_DST_W else: header = ofproto_v1_0.NXM_NX_IPV6_DST offset += nxm_put(buf, offset, header, rule) if len(rule.flow.nd_target): if len(rule.wc.nd_target_mask): header = ofproto_v1_0.NXM_NX_ND_TARGET_W else: header = ofproto_v1_0.NXM_NX_ND_TARGET offset += nxm_put(buf, offset, header, rule) # ARP if rule.flow.arp_spa != 0: if rule.wc.arp_spa_mask == UINT32_MAX: header = ofproto_v1_0.NXM_OF_ARP_SPA else: header = ofproto_v1_0.NXM_OF_ARP_SPA_W offset += nxm_put(buf, offset, header, rule) if rule.flow.arp_tpa != 0: if rule.wc.arp_tpa_mask == UINT32_MAX: header = ofproto_v1_0.NXM_OF_ARP_TPA else: header = ofproto_v1_0.NXM_OF_ARP_TPA_W offset += nxm_put(buf, offset, header, rule) if not rule.wc.wildcards & FWW_ARP_SHA: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_ARP_SHA, rule) 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) if rule.flow.pkt_mark != 0: if rule.wc.pkt_mark_mask == UINT32_MAX: header = ofproto_v1_0.NXM_NX_PKT_MARK else: header = ofproto_v1_0.NXM_NX_PKT_MARK_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: header = ofproto_v1_0.NXM_NX_TUN_ID else: header = ofproto_v1_0.NXM_NX_TUN_ID_W offset += nxm_put(buf, offset, header, rule) # XXX: Cookie for i in range(FLOW_N_REGS): if rule.wc.regs_bits & (1 << i): if rule.wc.regs_mask[i]: header = ofproto_v1_0.nxm_nx_reg_w(i) else: header = ofproto_v1_0.nxm_nx_reg(i) offset += nxm_put(buf, offset, header, rule) # Pad pad_len = round_up(offset) - offset msg_pack_into("%dx" % pad_len, buf, offset) # The returned length, the match_len, does not include the pad return offset - old_offset
def _putv6(self, buf, offset, value): msg_pack_into(self.pack_str, buf, offset, *value) return self.n_bytes
def put_header(self, buf, offset): msg_pack_into(ofproto_v1_0.NXM_HEADER_PACK_STRING, buf, offset, self.header) return struct.calcsize(ofproto_v1_0.NXM_HEADER_PACK_STRING)