X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fnx-match.c;h=f66c6556a8f12de051288df332755e3d470010f3;hb=520e9a2acdcf6136bf0a20586df6351ecf72dd3e;hp=5fc6aa24942f1253b95e1099ef70a14956790589;hpb=d31f1109f10e5ffb9bf266306b913ebf23781666;p=openvswitch diff --git a/lib/nx-match.c b/lib/nx-match.c index 5fc6aa24..f66c6556 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -18,6 +18,8 @@ #include "nx-match.h" +#include + #include "classifier.h" #include "dynamic-string.h" #include "ofp-util.h" @@ -76,16 +78,6 @@ static struct nxm_field nxm_fields[N_NXM_FIELDS] = { /* Hash table of 'nxm_fields'. */ static struct hmap all_nxm_fields = HMAP_INITIALIZER(&all_nxm_fields); -/* Possible masks for NXM_OF_ETH_DST_W. */ -static const uint8_t eth_all_0s[ETH_ADDR_LEN] - = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -static const uint8_t eth_all_1s[ETH_ADDR_LEN] - = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -static const uint8_t eth_mcast_1[ETH_ADDR_LEN] - = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00}; -static const uint8_t eth_mcast_0[ETH_ADDR_LEN] - = {0xfe, 0xff, 0xff, 0xff, 0xff, 0xff}; - static void nxm_init(void) { @@ -174,9 +166,6 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f, /* Metadata. */ case NFI_NXM_OF_IN_PORT: flow->in_port = ntohs(get_unaligned_be16(value)); - if (flow->in_port == OFPP_LOCAL) { - flow->in_port = ODPP_LOCAL; - } return 0; /* Ethernet header. */ @@ -193,18 +182,8 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f, if ((wc->wildcards & (FWW_DL_DST | FWW_ETH_MCAST)) != (FWW_DL_DST | FWW_ETH_MCAST)) { return NXM_DUP_TYPE; - } else if (eth_addr_equals(mask, eth_mcast_1)) { - wc->wildcards &= ~FWW_ETH_MCAST; - flow->dl_dst[0] = *(uint8_t *) value & 0x01; - } else if (eth_addr_equals(mask, eth_mcast_0)) { - wc->wildcards &= ~FWW_DL_DST; - memcpy(flow->dl_dst, value, ETH_ADDR_LEN); - flow->dl_dst[0] &= 0xfe; - } else if (eth_addr_equals(mask, eth_all_0s)) { - return 0; - } else if (eth_addr_equals(mask, eth_all_1s)) { - wc->wildcards &= ~(FWW_DL_DST | FWW_ETH_MCAST); - memcpy(flow->dl_dst, value, ETH_ADDR_LEN); + } else if (flow_wildcards_is_dl_dst_mask_valid(mask)) { + cls_rule_set_dl_dst_masked(rule, value, mask); return 0; } else { return NXM_BAD_MASK; @@ -363,6 +342,30 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f, flow->tp_dst = htons(*(uint8_t *) value); return 0; + /* IPv6 Neighbor Discovery. */ + case NFI_NXM_NX_ND_TARGET: + /* We've already verified that it's an ICMPv6 message. */ + if ((flow->tp_src != htons(ND_NEIGHBOR_SOLICIT)) + && (flow->tp_src != htons(ND_NEIGHBOR_ADVERT))) { + return NXM_BAD_PREREQ; + } + memcpy(&flow->nd_target, value, sizeof flow->nd_target); + return 0; + case NFI_NXM_NX_ND_SLL: + /* We've already verified that it's an ICMPv6 message. */ + if (flow->tp_src != htons(ND_NEIGHBOR_SOLICIT)) { + return NXM_BAD_PREREQ; + } + memcpy(flow->arp_sha, value, ETH_ADDR_LEN); + return 0; + case NFI_NXM_NX_ND_TLL: + /* We've already verified that it's an ICMPv6 message. */ + if (flow->tp_src != htons(ND_NEIGHBOR_ADVERT)) { + return NXM_BAD_PREREQ; + } + memcpy(flow->arp_tha, value, ETH_ADDR_LEN); + return 0; + /* ARP header. */ case NFI_NXM_OF_ARP_OP: if (ntohs(get_unaligned_be16(value)) > 255) { @@ -652,20 +655,15 @@ nxm_put_eth(struct ofpbuf *b, uint32_t header, static void nxm_put_eth_dst(struct ofpbuf *b, - uint32_t wc, const uint8_t value[ETH_ADDR_LEN]) + flow_wildcards_t wc, const uint8_t value[ETH_ADDR_LEN]) { switch (wc & (FWW_DL_DST | FWW_ETH_MCAST)) { case FWW_DL_DST | FWW_ETH_MCAST: break; - case FWW_DL_DST: - nxm_put_header(b, NXM_OF_ETH_DST_W); - ofpbuf_put(b, value, ETH_ADDR_LEN); - ofpbuf_put(b, eth_mcast_1, ETH_ADDR_LEN); - break; - case FWW_ETH_MCAST: + default: nxm_put_header(b, NXM_OF_ETH_DST_W); ofpbuf_put(b, value, ETH_ADDR_LEN); - ofpbuf_put(b, eth_mcast_0, ETH_ADDR_LEN); + ofpbuf_put(b, flow_wildcards_to_dl_dst_mask(wc), ETH_ADDR_LEN); break; case 0: nxm_put_eth(b, NXM_OF_ETH_DST, value); @@ -711,9 +709,6 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr) /* Metadata. */ if (!(wc & FWW_IN_PORT)) { uint16_t in_port = flow->in_port; - if (in_port == ODPP_LOCAL) { - in_port = OFPP_LOCAL; - } nxm_put_16(b, NXM_OF_IN_PORT, htons(in_port)); } @@ -811,6 +806,22 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr) case IPPROTO_ICMPV6: if (!(wc & FWW_TP_SRC)) { nxm_put_8(b, NXM_NX_ICMPV6_TYPE, ntohs(flow->tp_src)); + + if (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || + flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) { + if (!(wc & FWW_ND_TARGET)) { + nxm_put_ipv6(b, NXM_NX_ND_TARGET, &flow->nd_target, + &in6addr_exact); + } + if (!(wc & FWW_ARP_SHA) + && flow->tp_src == htons(ND_NEIGHBOR_SOLICIT)) { + nxm_put_eth(b, NXM_NX_ND_SLL, flow->arp_sha); + } + if (!(wc & FWW_ARP_THA) + && flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) { + nxm_put_eth(b, NXM_NX_ND_TLL, flow->arp_tha); + } + } } if (!(wc & FWW_TP_DST)) { nxm_put_8(b, NXM_NX_ICMPV6_CODE, ntohs(flow->tp_dst)); @@ -1234,7 +1245,7 @@ nxm_read_field(const struct nxm_field *src, const struct flow *flow) { switch (src->index) { case NFI_NXM_OF_IN_PORT: - return flow->in_port == ODPP_LOCAL ? OFPP_LOCAL : flow->in_port; + return flow->in_port; case NFI_NXM_OF_ETH_DST: return eth_addr_to_uint64(flow->dl_dst); @@ -1303,9 +1314,11 @@ nxm_read_field(const struct nxm_field *src, const struct flow *flow) #endif case NFI_NXM_NX_ARP_SHA: + case NFI_NXM_NX_ND_SLL: return eth_addr_to_uint64(flow->arp_sha); case NFI_NXM_NX_ARP_THA: + case NFI_NXM_NX_ND_TLL: return eth_addr_to_uint64(flow->arp_tha); case NFI_NXM_NX_TUN_ID_W: @@ -1319,6 +1332,7 @@ nxm_read_field(const struct nxm_field *src, const struct flow *flow) case NFI_NXM_NX_IPV6_SRC_W: case NFI_NXM_NX_IPV6_DST: case NFI_NXM_NX_IPV6_DST_W: + case NFI_NXM_NX_ND_TARGET: case N_NXM_FIELDS: NOT_REACHED(); } @@ -1392,6 +1406,9 @@ nxm_write_field(const struct nxm_field *dst, struct flow *flow, case NFI_NXM_NX_IPV6_DST_W: case NFI_NXM_NX_ICMPV6_TYPE: case NFI_NXM_NX_ICMPV6_CODE: + case NFI_NXM_NX_ND_TARGET: + case NFI_NXM_NX_ND_SLL: + case NFI_NXM_NX_ND_TLL: case N_NXM_FIELDS: NOT_REACHED(); }