X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fflow.c;h=fa7ae4f178327fa681b05c5e37832037f313e5fd;hb=777507385a993b3ca072c512dac30ba1e6354b42;hp=3f0bea5549d880a7d55a2c21497d57599d989cd9;hpb=25cfd5cac3ef31c8969db2efb067140cf4e7f08f;p=openvswitch diff --git a/lib/flow.c b/lib/flow.c index 3f0bea55..fa7ae4f1 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -203,11 +203,14 @@ parse_ipv6(struct ofpbuf *packet, struct flow *flow) } /* We only process the first fragment. */ - flow->nw_frag = FLOW_NW_FRAG_ANY; - if ((frag_hdr->ip6f_offlg & IP6F_OFF_MASK) != htons(0)) { - flow->nw_frag |= FLOW_NW_FRAG_LATER; - nexthdr = IPPROTO_FRAGMENT; - break; + if (frag_hdr->ip6f_offlg != htons(0)) { + if ((frag_hdr->ip6f_offlg & IP6F_OFF_MASK) == htons(0)) { + flow->nw_frag = FLOW_NW_FRAG_ANY; + } else { + flow->nw_frag |= FLOW_NW_FRAG_LATER; + nexthdr = IPPROTO_FRAGMENT; + break; + } } } } @@ -309,7 +312,9 @@ invalid: } -/* Initializes 'flow' members from 'packet', 'tun_id', and 'ofp_in_port'. +/* Initializes 'flow' members from 'packet', 'skb_priority', 'tun_id', and + * 'ofp_in_port'. + * * Initializes 'packet' header pointers as follows: * * - packet->l2 to the start of the Ethernet header. @@ -325,7 +330,7 @@ invalid: * present and has a correct length, and otherwise NULL. */ void -flow_extract(struct ofpbuf *packet, uint32_t priority, ovs_be64 tun_id, +flow_extract(struct ofpbuf *packet, uint32_t skb_priority, ovs_be64 tun_id, uint16_t ofp_in_port, struct flow *flow) { struct ofpbuf b = *packet; @@ -336,7 +341,7 @@ flow_extract(struct ofpbuf *packet, uint32_t priority, ovs_be64 tun_id, memset(flow, 0, sizeof *flow); flow->tun_id = tun_id; flow->in_port = ofp_in_port; - flow->priority = priority; + flow->skb_priority = skb_priority; packet->l2 = b.data; packet->l3 = NULL; @@ -499,7 +504,7 @@ flow_zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards) if (wc & FWW_ND_TARGET) { memset(&flow->nd_target, 0, sizeof flow->nd_target); } - flow->priority = 0; + flow->skb_priority = 0; } char * @@ -516,7 +521,7 @@ flow_format(struct ds *ds, const struct flow *flow) ds_put_format(ds, "priority%"PRIu32 ":tunnel%#"PRIx64 ":in_port%04"PRIx16, - flow->priority, + flow->skb_priority, ntohll(flow->tun_id), flow->in_port); @@ -935,6 +940,44 @@ flow_hash_fields_valid(enum nx_hash_fields fields) || fields == NX_HASH_FIELDS_SYMMETRIC_L4; } +/* Sets the VLAN VID that 'flow' matches to 'vid', which is interpreted as an + * OpenFlow 1.0 "dl_vlan" value: + * + * - If it is in the range 0...4095, 'flow->vlan_tci' is set to match + * that VLAN. Any existing PCP match is unchanged (it becomes 0 if + * 'flow' previously matched packets without a VLAN header). + * + * - If it is OFP_VLAN_NONE, 'flow->vlan_tci' is set to match a packet + * without a VLAN tag. + * + * - Other values of 'vid' should not be used. */ +void +flow_set_vlan_vid(struct flow *flow, ovs_be16 vid) +{ + if (vid == htons(OFP_VLAN_NONE)) { + flow->vlan_tci = htons(0); + } else { + vid &= htons(VLAN_VID_MASK); + flow->vlan_tci &= ~htons(VLAN_VID_MASK); + flow->vlan_tci |= htons(VLAN_CFI) | vid; + } +} + +/* Sets the VLAN PCP that 'flow' matches to 'pcp', which should be in the + * range 0...7. + * + * This function has no effect on the VLAN ID that 'flow' matches. + * + * After calling this function, 'flow' will not match packets without a VLAN + * header. */ +void +flow_set_vlan_pcp(struct flow *flow, uint8_t pcp) +{ + pcp &= 0x07; + flow->vlan_tci &= ~htons(VLAN_PCP_MASK); + flow->vlan_tci |= htons((pcp << VLAN_PCP_SHIFT) | VLAN_CFI); +} + /* Puts into 'b' a packet that flow_extract() would parse as having the given * 'flow'. * @@ -979,6 +1022,7 @@ flow_compose(struct ofpbuf *b, const struct flow *flow) b->l4 = tcp = ofpbuf_put_zeros(b, sizeof *tcp); tcp->tcp_src = flow->tp_src; tcp->tcp_dst = flow->tp_dst; + tcp->tcp_ctl = TCP_CTL(0, 5); } else if (flow->nw_proto == IPPROTO_UDP) { struct udp_header *udp; @@ -993,6 +1037,9 @@ flow_compose(struct ofpbuf *b, const struct flow *flow) icmp->icmp_code = ntohs(flow->tp_dst); } } + + ip->ip_tot_len = htons((uint8_t *) b->data + b->size + - (uint8_t *) b->l3); } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) { /* XXX */ } else if (flow->dl_type == htons(ETH_TYPE_ARP)) {