void flow_format(struct ds *ds, const struct flow *flow) { ds_put_format(ds, "priority:%"PRIu32 ",tunnel:%#"PRIx64 ",metadata:%#"PRIx64 ",in_port:%04"PRIx16, flow->skb_priority, ntohll(flow->tun_id), ntohll(flow->metadata), flow->in_port); ds_put_format(ds, ",tci("); if (flow->vlan_tci) { ds_put_format(ds, "vlan:%"PRIu16",pcp:%d", vlan_tci_to_vid(flow->vlan_tci), vlan_tci_to_pcp(flow->vlan_tci)); } else { ds_put_char(ds, '0'); } ds_put_format(ds, ") mac("ETH_ADDR_FMT"->"ETH_ADDR_FMT ") type:%04"PRIx16, ETH_ADDR_ARGS(flow->dl_src), ETH_ADDR_ARGS(flow->dl_dst), ntohs(flow->dl_type)); if (flow->dl_type == htons(ETH_TYPE_IPV6)) { ds_put_format(ds, " label:%#"PRIx32" proto:%"PRIu8" tos:%#"PRIx8 " ttl:%"PRIu8" ipv6(", ntohl(flow->ipv6_label), flow->nw_proto, flow->nw_tos, flow->nw_ttl); print_ipv6_addr(ds, &flow->ipv6_src); ds_put_cstr(ds, "->"); print_ipv6_addr(ds, &flow->ipv6_dst); ds_put_char(ds, ')'); } else { ds_put_format(ds, " proto:%"PRIu8" tos:%#"PRIx8" ttl:%"PRIu8 " ip("IP_FMT"->"IP_FMT")", flow->nw_proto, flow->nw_tos, flow->nw_ttl, IP_ARGS(&flow->nw_src), IP_ARGS(&flow->nw_dst)); } if (flow->nw_frag) { ds_put_format(ds, " frag(%s)", flow->nw_frag == FLOW_NW_FRAG_ANY ? "first" : flow->nw_frag == (FLOW_NW_FRAG_ANY | FLOW_NW_FRAG_LATER) ? "later" : "<error>"); } if (flow->tp_src || flow->tp_dst) { ds_put_format(ds, " port(%"PRIu16"->%"PRIu16")", ntohs(flow->tp_src), ntohs(flow->tp_dst)); } if (!eth_addr_is_zero(flow->arp_sha) || !eth_addr_is_zero(flow->arp_tha)) { ds_put_format(ds, " arp_ha("ETH_ADDR_FMT"->"ETH_ADDR_FMT")", ETH_ADDR_ARGS(flow->arp_sha), ETH_ADDR_ARGS(flow->arp_tha)); } }
void eth_format_masked(const uint8_t eth[ETH_ADDR_LEN], const uint8_t mask[ETH_ADDR_LEN], struct ds *s) { ds_put_format(s, ETH_ADDR_FMT, ETH_ADDR_ARGS(eth)); if (mask && !eth_mask_is_exact(mask)) { ds_put_format(s, "/"ETH_ADDR_FMT, ETH_ADDR_ARGS(mask)); } }
void flow_print(FILE *stream, const struct flow *flow) { fprintf(stream, "port %04x vlan-vid %04x vlan-pcp %02x src-mac "ETH_ADDR_FMT" " "dst-mac "ETH_ADDR_FMT" frm-type %04x ip-tos %02x ip-proto %02x " "src-ip "IP_FMT" dst-ip "IP_FMT" tp-src %d tp-dst %d", ntohs(flow->in_port), ntohs(flow->dl_vlan), flow->dl_vlan_pcp, ETH_ADDR_ARGS(flow->dl_src), ETH_ADDR_ARGS(flow->dl_dst), ntohs(flow->dl_type), flow->nw_tos, flow->nw_proto, IP_ARGS(&flow->nw_src), IP_ARGS(&flow->nw_dst), ntohs(flow->tp_src), ntohs(flow->tp_dst)); }
static void lex_token_format_value(const union mf_subvalue *value, enum lex_format format, struct ds *s) { switch (format) { case LEX_F_DECIMAL: ds_put_format(s, "%"PRIu64, ntohll(value->integer)); break; case LEX_F_HEXADECIMAL: mf_format_subvalue(value, s); break; case LEX_F_IPV4: ds_put_format(s, IP_FMT, IP_ARGS(value->ipv4)); break; case LEX_F_IPV6: ipv6_format_addr(&value->ipv6, s); break; case LEX_F_ETHERNET: ds_put_format(s, ETH_ADDR_FMT, ETH_ADDR_ARGS(value->mac)); break; default: OVS_NOT_REACHED(); } }
/* Attempts to make 'ml' learn from the fact that a frame from 'src_mac' was * just observed arriving from 'src_port' on the given 'vlan'. * * Returns nonzero if we actually learned something from this, zero if it just * confirms what we already knew. The nonzero return value is the tag of flows * that now need revalidation. * * The 'vlan' parameter is used to maintain separate per-VLAN learning tables. * Specify 0 if this behavior is undesirable. * * 'lock_type' specifies whether the entry should be locked or existing locks * are check. */ tag_type mac_learning_learn(struct mac_learning *ml, const uint8_t src_mac[ETH_ADDR_LEN], uint16_t vlan, uint16_t src_port, enum grat_arp_lock_type lock_type) { struct mac_entry *e; struct list *bucket; if (!is_learning_vlan(ml, vlan)) { return 0; } if (eth_addr_is_multicast(src_mac)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(30, 30); VLOG_DBG_RL(&rl, "multicast packet source "ETH_ADDR_FMT, ETH_ADDR_ARGS(src_mac)); return 0; } bucket = mac_table_bucket(ml, src_mac, vlan); e = search_bucket(bucket, src_mac, vlan); if (!e) { if (!list_is_empty(&ml->free)) { e = mac_entry_from_lru_node(ml->free.next); } else { e = mac_entry_from_lru_node(ml->lrus.next); list_remove(&e->hash_node); } memcpy(e->mac, src_mac, ETH_ADDR_LEN); list_push_front(bucket, &e->hash_node); e->port = -1; e->vlan = vlan; e->tag = make_unknown_mac_tag(ml, src_mac, vlan); e->grat_arp_lock = TIME_MIN; } if (lock_type != GRAT_ARP_LOCK_CHECK || time_now() >= e->grat_arp_lock) { /* Make the entry most-recently-used. */ list_remove(&e->lru_node); list_push_back(&ml->lrus, &e->lru_node); e->expires = time_now() + MAC_ENTRY_IDLE_TIME; if (lock_type == GRAT_ARP_LOCK_SET) { e->grat_arp_lock = time_now() + MAC_GRAT_ARP_LOCK_TIME; } /* Did we learn something? */ if (e->port != src_port) { tag_type old_tag = e->tag; e->port = src_port; e->tag = tag_create_random(); COVERAGE_INC(mac_learning_learned); return old_tag; } } return 0; }
static void ofl_msg_print_port_mod(struct ofl_msg_port_mod *msg, FILE *stream) { fprintf(stream, "{port=\""); ofl_port_print(stream, msg->port_no); fprintf(stream, "\", hwaddr=\""ETH_ADDR_FMT"\", config=\"0x%08"PRIx32"\", " "mask=\"0x%"PRIx32"\", adv=\"0x%"PRIx32"\"}", ETH_ADDR_ARGS(msg->hw_addr), msg->config, msg->mask, msg->advertise); }
/* Extracts the mac, IPv4 and IPv6 addresses from the * "nbrec_logical_router_port" parameter 'lrp'. Stores the IPv4 and * IPv6 addresses in the 'ipv4_addrs' and 'ipv6_addrs' fields of * 'laddrs', respectively. In addition, a link local IPv6 address * based on the 'mac' member of 'lrp' is added to the 'ipv6_addrs' * field. * * Return true if a valid 'mac' address is found in 'lrp', false otherwise. * * The caller must call destroy_lport_addresses(). */ bool extract_lrp_networks(const struct nbrec_logical_router_port *lrp, struct lport_addresses *laddrs) { memset(laddrs, 0, sizeof *laddrs); if (!eth_addr_from_string(lrp->mac, &laddrs->ea)) { laddrs->ea = eth_addr_zero; return false; } snprintf(laddrs->ea_s, sizeof laddrs->ea_s, ETH_ADDR_FMT, ETH_ADDR_ARGS(laddrs->ea)); for (int i = 0; i < lrp->n_networks; i++) { ovs_be32 ip4; struct in6_addr ip6; unsigned int plen; char *error; error = ip_parse_cidr(lrp->networks[i], &ip4, &plen); if (!error) { if (!ip4 || plen == 32) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); VLOG_WARN_RL(&rl, "bad 'networks' %s", lrp->networks[i]); continue; } add_ipv4_netaddr(laddrs, ip4, plen); continue; } free(error); error = ipv6_parse_cidr(lrp->networks[i], &ip6, &plen); if (!error) { if (plen == 128) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); VLOG_WARN_RL(&rl, "bad 'networks' %s", lrp->networks[i]); continue; } add_ipv6_netaddr(laddrs, ip6, plen); } else { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); VLOG_INFO_RL(&rl, "invalid syntax '%s' in networks", lrp->networks[i]); free(error); } } /* Always add the IPv6 link local address. */ struct in6_addr lla; in6_generate_lla(laddrs->ea, &lla); add_ipv6_netaddr(laddrs, lla, 64); return true; }
void ofl_structs_port_print(FILE *stream, struct ofl_port *port) { fprintf(stream, "{no=\""); ofl_port_print(stream, port->port_no); fprintf(stream, "\", hw_addr=\""ETH_ADDR_FMT"\", name=\"%s\", " "config=\"0x%"PRIx32"\", state=\"0x%"PRIx32"\", curr=\"0x%"PRIx32"\", " "adv=\"0x%"PRIx32"\", supp=\"0x%"PRIx32"\", peer=\"0x%"PRIx32"\", " "curr_spd=\"%ukbps\", max_spd=\"%ukbps\"}", ETH_ADDR_ARGS(port->hw_addr), port->name, port->config, port->state, port->curr, port->advertised, port->supported, port->peer, port->curr_speed, port->max_speed); }
/* Extracts the mac, IPv4 and IPv6 addresses from * 'address' which * should be of the format "MAC [IP1 IP2 ..] .." where IPn should be a * valid IPv4 or IPv6 address and stores them in the 'ipv4_addrs' and * 'ipv6_addrs' fields of 'laddrs'. There may be additional content in * 'address' after "MAC [IP1 IP2 .. ]". The value of 'ofs' that is * returned indicates the offset where that additional content begins. * * Returns true if at least 'MAC' is found in 'address', false otherwise. * * The caller must call destroy_lport_addresses(). */ bool extract_addresses(const char *address, struct lport_addresses *laddrs, int *ofs) { memset(laddrs, 0, sizeof *laddrs); const char *buf = address; const char *const start = buf; int buf_index = 0; const char *buf_end = buf + strlen(address); if (!ovs_scan_len(buf, &buf_index, ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(laddrs->ea))) { laddrs->ea = eth_addr_zero; *ofs = 0; return false; } snprintf(laddrs->ea_s, sizeof laddrs->ea_s, ETH_ADDR_FMT, ETH_ADDR_ARGS(laddrs->ea)); ovs_be32 ip4; struct in6_addr ip6; unsigned int plen; char *error; /* Loop through the buffer and extract the IPv4/IPv6 addresses * and store in the 'laddrs'. Break the loop if invalid data is found. */ buf += buf_index; while (buf < buf_end) { buf_index = 0; error = ip_parse_cidr_len(buf, &buf_index, &ip4, &plen); if (!error) { add_ipv4_netaddr(laddrs, ip4, plen); buf += buf_index; continue; } free(error); error = ipv6_parse_cidr_len(buf, &buf_index, &ip6, &plen); if (!error) { add_ipv6_netaddr(laddrs, ip6, plen); } else { free(error); break; } buf += buf_index; } *ofs = buf - start; return true; }
/* Extracts the mac, IPv4 and IPv6 addresses from * 'address' which * should be of the format 'MAC [IP1 IP2 ..]" where IPn should be a * valid IPv4 or IPv6 address and stores them in the 'ipv4_addrs' and * 'ipv6_addrs' fields of 'laddrs'. * * Return true if at least 'MAC' is found in 'address', false otherwise. * * The caller must call destroy_lport_addresses(). */ bool extract_lsp_addresses(const char *address, struct lport_addresses *laddrs) { memset(laddrs, 0, sizeof *laddrs); const char *buf = address; int buf_index = 0; const char *buf_end = buf + strlen(address); if (!ovs_scan_len(buf, &buf_index, ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(laddrs->ea))) { laddrs->ea = eth_addr_zero; return false; } snprintf(laddrs->ea_s, sizeof laddrs->ea_s, ETH_ADDR_FMT, ETH_ADDR_ARGS(laddrs->ea)); ovs_be32 ip4; struct in6_addr ip6; unsigned int plen; char *error; /* Loop through the buffer and extract the IPv4/IPv6 addresses * and store in the 'laddrs'. Break the loop if invalid data is found. */ buf += buf_index; while (buf < buf_end) { buf_index = 0; error = ip_parse_cidr_len(buf, &buf_index, &ip4, &plen); if (!error) { add_ipv4_netaddr(laddrs, ip4, plen); buf += buf_index; continue; } free(error); error = ipv6_parse_cidr_len(buf, &buf_index, &ip6, &plen); if (!error) { add_ipv6_netaddr(laddrs, ip6, plen); } else { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); VLOG_INFO_RL(&rl, "invalid syntax '%s' in address", address); free(error); break; } buf += buf_index; } return true; }
void ofl_structs_oxm_tlv_print(FILE *stream, struct ofl_match_tlv *f) { uint8_t field = OXM_FIELD(f->header); switch (field) { case OFPXMT_OFB_IN_PORT: fprintf(stream, "in_port=\"%d\"", *((uint32_t*) f->value)); break; case OFPXMT_OFB_IN_PHY_PORT: fprintf(stream, "in_phy_port=\"%d\"", *((uint32_t*) f->value)); break; case OFPXMT_OFB_VLAN_VID: { uint16_t v = *((uint16_t *) f->value); if (v == OFPVID_NONE) fprintf(stream, "vlan_vid= none"); else if (v == OFPVID_PRESENT && OXM_HASMASK(f->header)) fprintf(stream, "vlan_vid= any"); else fprintf(stream, "vlan_vid=\"%d\"",v & VLAN_VID_MASK); break; } case OFPXMT_OFB_VLAN_PCP: fprintf(stream, "vlan_pcp=\"%d\"", *f->value & 0x7); break; case OFPXMT_OFB_ETH_TYPE: fprintf(stream, "eth_type=\"0x%x\"", *((uint16_t *) f->value)); break; case OFPXMT_OFB_TCP_SRC: fprintf(stream, "tcp_src=\"%d\"", *((uint16_t*) f->value)); break; case OFPXMT_OFB_TCP_DST: fprintf(stream, "tcp_dst=\"%d\"", *((uint16_t*) f->value)); break; case OFPXMT_OFB_UDP_SRC: fprintf(stream, "udp_src=\"%d\"", *((uint16_t*) f->value)); break; case OFPXMT_OFB_UDP_DST: fprintf(stream, "udp_dst=\"%d\"", *((uint16_t*) f->value)); break; case OFPXMT_OFB_SCTP_SRC: fprintf(stream, "sctp_src=\"%d\"", *((uint16_t*) f->value)); break; case OFPXMT_OFB_SCTP_DST: fprintf(stream, "sctp_dst=\"%d\"", *((uint16_t*) f->value)); break; case OFPXMT_OFB_ETH_SRC: fprintf(stream, "eth_src=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); if (OXM_HASMASK(f->header)) { fprintf(stream, ", eth_src_mask=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value + 6)); } break; case OFPXMT_OFB_ETH_DST: fprintf(stream, "eth_dst=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); if (OXM_HASMASK(f->header)) { fprintf(stream, ", eth_dst_mask=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value + 6)); } break; case OFPXMT_OFB_IPV4_DST: fprintf(stream, "ipv4_dst=\""IP_FMT"\"", IP_ARGS(f->value)); if (OXM_HASMASK(f->header)) { fprintf(stream, ", ipv4_dst_mask=\""IP_FMT"\"", IP_ARGS(f->value + 4)); } break; case OFPXMT_OFB_IPV4_SRC: fprintf(stream, "ipv4_src=\""IP_FMT"\"", IP_ARGS(f->value)); if (OXM_HASMASK(f->header)) { fprintf(stream, ", ipv4_src_mask=\""IP_FMT"\"", IP_ARGS(f->value + 4)); } break; case OFPXMT_OFB_IP_PROTO: fprintf(stream, "ip_proto=\"%d\"", *f->value); break; case OFPXMT_OFB_IP_DSCP: fprintf(stream, "ip_dscp=\"%d\"", *f->value & 0x3f); break; case OFPXMT_OFB_IP_ECN: fprintf(stream, "ip_ecn=\"%d\"", *f->value & 0x3); break; case OFPXMT_OFB_ICMPV4_TYPE: fprintf(stream, "icmpv4_type= \"%d\"", *f->value); break; case OFPXMT_OFB_ICMPV4_CODE: fprintf(stream, "icmpv4_code=\"%d\"", *f->value); break; case OFPXMT_OFB_ARP_SHA: fprintf(stream, "arp_sha=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); if (OXM_HASMASK(f->header)) { fprintf(stream, ", arp_sha_mask=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value + 6)); } break; case OFPXMT_OFB_ARP_THA: fprintf(stream, "arp_tha=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); if (OXM_HASMASK(f->header)) { fprintf(stream, ", arp_tha_mask=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value + 6)); } break; case OFPXMT_OFB_ARP_SPA: fprintf(stream, "arp_spa=\""IP_FMT"\"", IP_ARGS(f->value)); if (OXM_HASMASK(f->header)) { fprintf(stream, ", arp_sha_mask=\""IP_FMT"\"", IP_ARGS(f->value + 4)); } break; case OFPXMT_OFB_ARP_TPA: fprintf(stream, "arp_tpa=\""IP_FMT"\"", IP_ARGS(f->value)); if (OXM_HASMASK(f->header)) { fprintf(stream, ", arp_tpa_mask=\""IP_FMT"\"", IP_ARGS(f->value + 4)); } break; case OFPXMT_OFB_ARP_OP: fprintf(stream, "arp_op=\"0x%x\"", *((uint16_t*) f->value)); break; case OFPXMT_OFB_IPV6_SRC: { char addr_str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, f->value, addr_str, INET6_ADDRSTRLEN); fprintf(stream, "nw_src_ipv6=\"%s\"", addr_str); if (OXM_HASMASK(f->header)) { inet_ntop(AF_INET6, f->value + 16, addr_str, INET6_ADDRSTRLEN); fprintf(stream, ", nw_src_ipv6_mask=\"%s\"", addr_str); } break; } case OFPXMT_OFB_IPV6_DST: { char addr_str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, f->value, addr_str, INET6_ADDRSTRLEN); fprintf(stream, "nw_dst_ipv6=\"%s\"", addr_str); if (OXM_HASMASK(f->header)) { inet_ntop(AF_INET6, f->value + 16, addr_str, INET6_ADDRSTRLEN); fprintf(stream, ", nw_dst_ipv6_mask=\"%s\"", addr_str); } break; } case OFPXMT_OFB_IPV6_ND_TARGET: { char addr_str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, f->value, addr_str, INET6_ADDRSTRLEN); fprintf(stream, "ipv6_nd_target=\"%s\"", addr_str); break; } case OFPXMT_OFB_IPV6_ND_SLL: fprintf(stream, "ipv6_nd_sll=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); break; case OFPXMT_OFB_IPV6_ND_TLL: fprintf(stream, "ipv6_nd_tll=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); break; case OFPXMT_OFB_IPV6_FLABEL: fprintf(stream, "ipv6_flow_label=\"%d\"", *((uint32_t*) f->value) & 0x000fffff); if (OXM_HASMASK(f->header)) { fprintf(stream, ", ipv6_flow_label_mask=\"%d\"", *((uint32_t*) (f->value+4))); } break; case OFPXMT_OFB_ICMPV6_TYPE: fprintf(stream, "icmpv6_type=\"%d\"", *f->value); break; case OFPXMT_OFB_ICMPV6_CODE: fprintf(stream, "icmpv6_code=\"%d\"", *f->value); break; case OFPXMT_OFB_MPLS_LABEL: fprintf(stream, "mpls_label=\"%d\"",((uint32_t) *f->value) & 0x000fffff); break; case OFPXMT_OFB_MPLS_TC: fprintf(stream, "mpls_tc=\"%d\"", *f->value & 0x3); break; case OFPXMT_OFB_MPLS_BOS: fprintf(stream, "mpls_bos=\"%d\"", *f->value & 0xfe); break; case OFPXMT_OFB_METADATA: fprintf(stream, "metadata=\"0x%llx\"", *((uint64_t*) f->value)); if (OXM_HASMASK(f->header)) { fprintf(stream, ", metadata_mask=\"0x%llx\"", *((uint64_t*)(f->value+8))); } break; case OFPXMT_OFB_PBB_ISID : fprintf(stream, "pbb_isid=\"%d\"", *((uint32_t*) f->value)); if (OXM_HASMASK(f->header)) { fprintf(stream, ", pbb_isid_mask=\"%d\"", *((uint32_t*)(f->value+4))); } break; case OFPXMT_OFB_TUNNEL_ID: fprintf(stream, "tunnel_id=\"%lld\"", *((uint64_t*) f->value)); if (OXM_HASMASK(f->header)) { fprintf(stream, ", tunnel_id_mask=\"%lld\"", *((uint64_t*)(f->value+8))); } break; case OFPXMT_OFB_IPV6_EXTHDR: fprintf(stream, "ext_hdr=\""); ofl_ipv6_ext_hdr_print(stream, *((uint16_t*) f->value)); fprintf(stream, "\""); if (OXM_HASMASK(f->header)) { fprintf(stream, ", ext_hdr_mask=\"0x%x\"", *((uint16_t*)(f->value+4))); } break; default: fprintf(stream, "unknown type %d", field); } }
void print_oxm_tlv(FILE *stream, struct ofl_match_tlv *f, size_t *size){ if (f->header == OXM_OF_IN_PORT){ fprintf(stream, "in_port=%d",*((uint32_t*) f->value)); *size -= 8; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_IN_PHY_PORT){ fprintf(stream, "in_phy_port=%d",*((uint32_t*) f->value)); *size -= 8; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_VLAN_VID){ if ((uint16_t) *f->value == OFPVID_NONE) fprintf(stream, "vlan_vid= none"); else if ((uint16_t) *f->value == OFPVID_PRESENT) fprintf(stream, "vlan_vid= present"); else fprintf(stream, "vlan_vid= %d",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_VLAN_PCP){ fprintf(stream, "vlan_pcp= %d", *f->value & 0x7); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_ETH_TYPE){ uint16_t *v = (uint16_t *) f->value; fprintf(stream, "eth_type=0x"); fprintf(stream,"%x", *v); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_TCP_SRC){ fprintf(stream, "tcp_src=%d",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_TCP_DST){ fprintf(stream, "tcp_dst=%d",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_UDP_SRC){ fprintf(stream, "udp_src=%d",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_UDP_DST){ fprintf(stream, "udp_dst=%d",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_SCTP_SRC){ fprintf(stream, "sctp_src=%d",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_SCTP_DST){ fprintf(stream, "sctp_dst=%d",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_ETH_SRC || f->header == OXM_OF_ETH_SRC_W){ fprintf(stream, "eth_src=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); *size -= 10; if (OXM_HASMASK(f->header)){ *size -= 6; fprintf(stream, "eth_src_mask=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value + 6)); } if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_ETH_DST || f->header == OXM_OF_ETH_DST_W){ fprintf(stream, "eth_dst=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); *size -= 10; if (OXM_HASMASK(f->header)){ *size -= 6; fprintf(stream, "eth_dst_mask=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value + 6)); } if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_IPV4_SRC || f->header == OXM_OF_IPV4_SRC_W){ fprintf(stream, "ipv4_src=\""IP_FMT"\"",IP_ARGS(f->value)); *size -= 8; if (OXM_HASMASK(f->header)){ *size -= 4; fprintf(stream, "ipv4_src_mask=\""IP_FMT"\"",IP_ARGS(f->value + 4)); } if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_IP_PROTO){ fprintf(stream, "ip_proto= %d", *f->value); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_IP_DSCP){ fprintf(stream, "ip_dscp= %d", *f->value & 0x3f); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_IP_ECN){ fprintf(stream, "ip_ecn= %d", *f->value & 0x3); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_ICMPV4_TYPE){ fprintf(stream, "icmpv4_type= %d", *f->value); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_ICMPV4_CODE){ fprintf(stream, "icmpv4_code= %d", *f->value); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_IPV4_DST || f->header == OXM_OF_IPV4_DST_W){ fprintf(stream, "ipv4_dst=\""IP_FMT"\"",IP_ARGS(f->value)); *size -= 8; if (OXM_HASMASK(f->header)){ *size -= 4; fprintf(stream, "ipv4_dst_mask=\""IP_FMT"\"",IP_ARGS(f->value + 4)); } if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_ARP_SPA || f->header == OXM_OF_ARP_SPA_W ){ fprintf(stream, "arp_sha=\""IP_FMT"\"",IP_ARGS(f->value)); *size -= 8; if (OXM_HASMASK(f->header)){ *size -= 4; fprintf(stream, "arp_sha_mask=\""IP_FMT"\"",IP_ARGS(f->value + 4)); } if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_ARP_TPA || f->header == OXM_OF_ARP_TPA_W){ fprintf(stream, "arp_tpa=\""IP_FMT"\"",IP_ARGS(f->value)); *size -= 8; if (OXM_HASMASK(f->header)){ *size -= 4; fprintf(stream, "arp_tpa_mask=\""IP_FMT"\"",IP_ARGS(f->value + 4)); } if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_ARP_OP){ uint16_t *v = (uint16_t *) f->value; fprintf(stream, "arp_op=0x"); fprintf(stream,"%x", *v); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_IPV6_SRC || f->header == OXM_OF_IPV6_SRC_W ){ char addr_str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, f->value, addr_str, INET6_ADDRSTRLEN); *size -= 20; fprintf(stream, "nw_src_ipv6=\"%s\"", addr_str); if (OXM_HASMASK(f->header)){ *size -= 16; inet_ntop(AF_INET6, f->value + 16, addr_str, INET6_ADDRSTRLEN); fprintf(stream, "nw_src_ipv6_mask=\"%s\"", addr_str); } if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_IPV6_DST || f->header == OXM_OF_IPV6_DST_W){ char addr_str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, f->value, addr_str, INET6_ADDRSTRLEN); *size -= 20; fprintf(stream, "nw_dst_ipv6=\"%s\"", addr_str); if (OXM_HASMASK(f->header)){ *size -= 16; inet_ntop(AF_INET6, f->value + 16, addr_str, INET6_ADDRSTRLEN); fprintf(stream, "nw_dst_ipv6_mask=\"%s\"", addr_str); } if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_IPV6_ND_TARGET){ char addr_str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, f->value, addr_str, INET6_ADDRSTRLEN); *size -= 20; fprintf(stream, "ipv6_nd_target=\"%s\"", addr_str); if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_IPV6_ND_SLL){ fprintf(stream, "ipv6_nd_sll=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); *size -= 10; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_IPV6_ND_TLL){ fprintf(stream, "ipv6_nd_tll=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); *size -= 10; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_IPV6_FLABEL){ uint32_t mask = 0xfffff; fprintf(stream, "ipv6_flow_label=%x",((uint32_t) *f->value) & mask ); *size -= 8; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_ICMPV6_TYPE){ fprintf(stream, "icmpv6_type= %d", *f->value); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_ICMPV6_CODE){ fprintf(stream, "icmpv6_code= %d", *f->value); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_MPLS_LABEL){ uint32_t mask = 0xfffff; fprintf(stream, "mpls_label=%x",((uint32_t) *f->value) & mask ); *size -= 8; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_MPLS_TC){ fprintf(stream, "mpls_tc= %d", *f->value & 0x3); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (f->header == OXM_OF_METADATA || f->header == OXM_OF_METADATA_W){ fprintf(stream, "metadata= %lld", (uint64_t) *f->value); *size -= 12; if (OXM_HASMASK(f->header)){ fprintf(stream, "metadata_mask= %lld", (uint64_t) *(f->value + 8)); *size -= 8; } if (*size > 4) fprintf(stream, ", "); } }
void format_odp_action(struct ds *ds, const struct nlattr *a) { const uint8_t *eth; ovs_be32 ip; if (nl_attr_get_size(a) != odp_action_len(nl_attr_type(a))) { ds_put_format(ds, "bad length %zu, expected %d for: ", nl_attr_get_size(a), odp_action_len(nl_attr_type(a))); format_generic_odp_action(ds, a); return; } switch (nl_attr_type(a)) { case OVS_ACTION_ATTR_OUTPUT: ds_put_format(ds, "%"PRIu16, nl_attr_get_u32(a)); break; case OVS_ACTION_ATTR_USERSPACE: ds_put_format(ds, "userspace(%"PRIu64")", nl_attr_get_u64(a)); break; case OVS_ACTION_ATTR_SET_TUNNEL: ds_put_format(ds, "set_tunnel(%#"PRIx64")", ntohll(nl_attr_get_be64(a))); break; case OVS_ACTION_ATTR_PUSH_VLAN: ds_put_format(ds, "push_vlan(vid=%"PRIu16",pcp=%d)", vlan_tci_to_vid(nl_attr_get_be16(a)), vlan_tci_to_pcp(nl_attr_get_be16(a))); break; case OVS_ACTION_ATTR_POP_VLAN: ds_put_format(ds, "pop_vlan"); break; case OVS_ACTION_ATTR_SET_DL_SRC: eth = nl_attr_get_unspec(a, ETH_ADDR_LEN); ds_put_format(ds, "set_dl_src("ETH_ADDR_FMT")", ETH_ADDR_ARGS(eth)); break; case OVS_ACTION_ATTR_SET_DL_DST: eth = nl_attr_get_unspec(a, ETH_ADDR_LEN); ds_put_format(ds, "set_dl_dst("ETH_ADDR_FMT")", ETH_ADDR_ARGS(eth)); break; case OVS_ACTION_ATTR_SET_NW_SRC: ip = nl_attr_get_be32(a); ds_put_format(ds, "set_nw_src("IP_FMT")", IP_ARGS(&ip)); break; case OVS_ACTION_ATTR_SET_NW_DST: ip = nl_attr_get_be32(a); ds_put_format(ds, "set_nw_dst("IP_FMT")", IP_ARGS(&ip)); break; case OVS_ACTION_ATTR_SET_NW_TOS: ds_put_format(ds, "set_nw_tos(%"PRIu8")", nl_attr_get_u8(a)); break; case OVS_ACTION_ATTR_SET_TP_SRC: ds_put_format(ds, "set_tp_src(%"PRIu16")", ntohs(nl_attr_get_be16(a))); break; case OVS_ACTION_ATTR_SET_TP_DST: ds_put_format(ds, "set_tp_dst(%"PRIu16")", ntohs(nl_attr_get_be16(a))); break; case OVS_ACTION_ATTR_SET_PRIORITY: ds_put_format(ds, "set_priority(%#"PRIx32")", nl_attr_get_u32(a)); break; case OVS_ACTION_ATTR_POP_PRIORITY: ds_put_cstr(ds, "pop_priority"); break; default: format_generic_odp_action(ds, a); break; } }
void format_odp_action(struct ds *ds, const union odp_action *a) { switch (a->type) { case ODPAT_OUTPUT: ds_put_format(ds, "%"PRIu16, a->output.port); break; case ODPAT_OUTPUT_GROUP: ds_put_format(ds, "g%"PRIu16, a->output_group.group); break; case ODPAT_CONTROLLER: ds_put_format(ds, "ctl(%"PRIu32")", a->controller.arg); break; case ODPAT_SET_TUNNEL: ds_put_format(ds, "set_tunnel(0x%08"PRIx32")", ntohl(a->tunnel.tun_id)); break; case ODPAT_SET_VLAN_VID: ds_put_format(ds, "set_vlan(%"PRIu16")", ntohs(a->vlan_vid.vlan_vid)); break; case ODPAT_SET_VLAN_PCP: ds_put_format(ds, "set_vlan_pcp(%"PRIu8")", a->vlan_pcp.vlan_pcp); break; case ODPAT_STRIP_VLAN: ds_put_format(ds, "strip_vlan"); break; case ODPAT_SET_DL_SRC: ds_put_format(ds, "set_dl_src("ETH_ADDR_FMT")", ETH_ADDR_ARGS(a->dl_addr.dl_addr)); break; case ODPAT_SET_DL_DST: ds_put_format(ds, "set_dl_dst("ETH_ADDR_FMT")", ETH_ADDR_ARGS(a->dl_addr.dl_addr)); break; case ODPAT_SET_NW_SRC: ds_put_format(ds, "set_nw_src("IP_FMT")", IP_ARGS(&a->nw_addr.nw_addr)); break; case ODPAT_SET_NW_DST: ds_put_format(ds, "set_nw_dst("IP_FMT")", IP_ARGS(&a->nw_addr.nw_addr)); break; case ODPAT_SET_NW_TOS: ds_put_format(ds, "set_nw_tos(%"PRIu8")", a->nw_tos.nw_tos); break; case ODPAT_SET_TP_SRC: ds_put_format(ds, "set_tp_src(%"PRIu16")", ntohs(a->tp_port.tp_port)); break; case ODPAT_SET_TP_DST: ds_put_format(ds, "set_tp_dst(%"PRIu16")", ntohs(a->tp_port.tp_port)); break; case ODPAT_SET_PRIORITY: ds_put_format(ds, "set_priority(0x%"PRIx32")", a->priority.priority); break; case ODPAT_POP_PRIORITY: ds_put_cstr(ds, "pop_priority"); break; default: ds_put_format(ds, "***bad action 0x%"PRIx16"***", a->type); break; } }
void print_oxm_tlv(FILE *stream, struct ofl_match_tlv *f, size_t *size){ uint8_t field = OXM_FIELD(f->header); if (field == OFPXMT_OFB_IN_PORT){ fprintf(stream, "in_port=\"%d\"",*((uint32_t*) f->value)); *size -= 8; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IN_PHY_PORT){ fprintf(stream, "in_phy_port=\"%d\"",*((uint32_t*) f->value)); *size -= 8; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_VLAN_VID){ uint16_t *v = (uint16_t *) f->value; if (*v == OFPVID_NONE) fprintf(stream, "vlan_vid= none"); else if (*v == OFPVID_PRESENT && OXM_HASMASK(f->header)) fprintf(stream, "vlan_vid= any"); else fprintf(stream, "vlan_vid=\"%d\"",*v & VLAN_VID_MASK); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_VLAN_PCP){ fprintf(stream, "vlan_pcp=\"%d\"", *f->value & 0x7); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_ETH_TYPE){ uint16_t *v = (uint16_t *) f->value; fprintf(stream, "eth_type="); fprintf(stream,"\"0x%x\"", *v); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_TCP_SRC){ fprintf(stream, "tcp_src=\"%d\"",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_TCP_DST){ fprintf(stream, "tcp_dst=\"%d\"",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_UDP_SRC){ fprintf(stream, "udp_src=\"%d\"",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_UDP_DST){ fprintf(stream, "udp_dst=\"%d\"",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_SCTP_SRC){ fprintf(stream, "sctp_src=\"%d\"",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_SCTP_DST){ fprintf(stream, "sctp_dst=\"%d\"",*((uint16_t*) f->value)); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_ETH_SRC){ fprintf(stream, "eth_src=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); *size -= 10; if (OXM_HASMASK(f->header)){ *size -= 6; fprintf(stream, ", eth_src_mask=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value + 6)); } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_ETH_DST){ fprintf(stream, "eth_dst=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); *size -= 10; if (OXM_HASMASK(f->header)){ *size -= 6; fprintf(stream, ", eth_dst_mask=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value + 6)); } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IPV4_DST){ fprintf(stream, "ipv4_dst=\""IP_FMT"\"",IP_ARGS(f->value)); *size -= 8; if (OXM_HASMASK(f->header)){ *size -= 4; fprintf(stream, ", ipv4_dst_mask=\""IP_FMT"\"",IP_ARGS(f->value + 4)); } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IPV4_SRC){ fprintf(stream, "ipv4_src=\""IP_FMT"\"",IP_ARGS(f->value)); *size -= 8; if (OXM_HASMASK(f->header)){ *size -= 4; fprintf(stream, ", ipv4_src_mask=\""IP_FMT"\"",IP_ARGS(f->value + 4)); } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IP_PROTO){ fprintf(stream, "ip_proto=\"%d\"", *f->value); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IP_DSCP){ fprintf(stream, "ip_dscp=\"%d\"", *f->value & 0x3f); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IP_ECN){ fprintf(stream, "ip_ecn=\"%d\"", *f->value & 0x3); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_ICMPV4_TYPE){ fprintf(stream, "icmpv4_type= \"%d\"", *f->value); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_ICMPV4_CODE){ fprintf(stream, "icmpv4_code=\"%d\"", *f->value); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_ARP_SHA){ fprintf(stream, "arp_sha=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); *size -= 10; if (OXM_HASMASK(f->header)){ *size -= 6; fprintf(stream, ", arp_sha_mask=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value + 6)); } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_ARP_THA){ fprintf(stream, "arp_tha=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); *size -= 10; if (OXM_HASMASK(f->header)){ *size -= 6; fprintf(stream, ", arp_tha_mask=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value + 6)); } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_ARP_SPA){ fprintf(stream, "arp_spa=\""IP_FMT"\"",IP_ARGS(f->value)); *size -= 8; if (OXM_HASMASK(f->header)){ *size -= 4; fprintf(stream, ", arp_sha_mask=\""IP_FMT"\"",IP_ARGS(f->value + 4)); } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_ARP_TPA){ fprintf(stream, "arp_tpa=\""IP_FMT"\"",IP_ARGS(f->value)); *size -= 8; if (OXM_HASMASK(f->header)){ *size -= 4; fprintf(stream, ", arp_tpa_mask=\""IP_FMT"\"",IP_ARGS(f->value + 4)); } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_ARP_OP){ uint16_t *v = (uint16_t *) f->value; fprintf(stream, "arp_op=\"0x"); fprintf(stream,"%x\"", *v); *size -= 6; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IPV6_SRC){ char addr_str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, f->value, addr_str, INET6_ADDRSTRLEN); *size -= 20; fprintf(stream, "nw_src_ipv6=\"%s\"", addr_str); if (OXM_HASMASK(f->header)){ *size -= 16; inet_ntop(AF_INET6, f->value + 16, addr_str, INET6_ADDRSTRLEN); fprintf(stream, ", nw_src_ipv6_mask=\"%s\"", addr_str); } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IPV6_DST){ char addr_str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, f->value, addr_str, INET6_ADDRSTRLEN); *size -= 20; fprintf(stream, "nw_dst_ipv6=\"%s\"", addr_str); if (OXM_HASMASK(f->header)){ *size -= 16; inet_ntop(AF_INET6, f->value + 16, addr_str, INET6_ADDRSTRLEN); fprintf(stream, ", nw_dst_ipv6_mask=\"%s\"", addr_str); } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IPV6_ND_TARGET){ char addr_str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, f->value, addr_str, INET6_ADDRSTRLEN); *size -= 20; fprintf(stream, "ipv6_nd_target=\"%s\"", addr_str); if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IPV6_ND_SLL){ fprintf(stream, "ipv6_nd_sll=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); *size -= 10; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IPV6_ND_TLL){ fprintf(stream, "ipv6_nd_tll=\""ETH_ADDR_FMT"\"", ETH_ADDR_ARGS(f->value)); *size -= 10; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IPV6_FLABEL){ uint32_t mask = 0x000fffff; *size -= 8; fprintf(stream, "ipv6_flow_label=\"%d\"",*((uint32_t*) f->value) & mask ); if (OXM_HASMASK(f->header)){ uint8_t *flabel_mask = (uint8_t*) f->value + 4; *size -= 4; fprintf(stream, ", ipv6_flow_label_mask=\"%d\"",*((uint32_t*)flabel_mask)); } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_ICMPV6_TYPE){ fprintf(stream, "icmpv6_type=\"%d\"", *f->value); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_ICMPV6_CODE){ fprintf(stream, "icmpv6_code=\"%d\"", *f->value); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_MPLS_LABEL){ uint32_t mask = 0xfffff; fprintf(stream, "mpls_label=\"%d\"",((uint32_t) *f->value) & mask ); *size -= 8; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_MPLS_TC){ fprintf(stream, "mpls_tc=\"%d\"", *f->value & 0x3); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_MPLS_BOS){ fprintf(stream, "mpls_bos=\"%d\"", *f->value & 0xfe); *size -= 5; if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_METADATA){ fprintf(stream, "metadata=\"%lld\"", *((uint64_t*) f->value)); *size -= 12; if (OXM_HASMASK(f->header)){ fprintf(stream, ", metadata_mask=\"%lld\"", *((uint64_t*) f->value+ 8 )); *size -= 8; } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_PBB_ISID ){ fprintf(stream, "pbb_isid=\"%d\"",*((uint32_t*) f->value)); *size -= 8; if (OXM_HASMASK(f->header)){ fprintf(stream, ", pbb_isid_mask=\"%d\"", *((uint32_t*) f->value +4)); *size -= 4; } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_TUNNEL_ID){ fprintf(stream, "tunnel_id=\"%lld\"", *((uint64_t*) f->value)); *size -= 12; if (OXM_HASMASK(f->header)){ fprintf(stream, ", tunnel_id_mask=\"%lld\"", *((uint64_t*) f->value+ 8 )); *size -= 8; } if (*size > 4) fprintf(stream, ", "); } else if (field == OFPXMT_OFB_IPV6_EXTHDR){ fprintf(stream, "ext_hdr=\\"); ofl_ipv6_ext_hdr_print(stream, *((uint16_t*) f->value) ); *size -= 6; if (OXM_HASMASK(f->header)){ *size -= 2; fprintf(stream, ", ext_hdr_mask=\"0x%x\"",*((uint16_t*) f->value + 4)); } if (*size > 4) fprintf(stream, ", "); } }