Thanks Ben, on what Linux version you are testing this? When I sent out the patch yesterday I had tested "make C=1" on Ubuntu 11.10(3.0 kernel) and CentOS 6.2(2.6 kernel) and had not seen sparse issues. I re-ran "make C=1" again today with the patch I sent out yesterday and didn't see any warnings. Please let me know on what version you are running this I will fix it.
Thanks Ravi -----Original Message----- From: Ben Pfaff [mailto:b...@nicira.com] Sent: Tuesday, March 13, 2012 10:36 AM To: Kerur, Ravi Cc: je...@nicira.com; dev@openvswitch.org Subject: Re: MPLS important comments (was: Re: [ovs-dev] Patch for MPLS) Thanks for the patch, it applies cleanly against current "master". (I had missed it on the first pass through my inbox this morning.) I see the following "sparse" warnings for the kernel code. It otherwise builds cleanly, and I can confirm that the unit tests pass for me. actions.c:244:36: warning: incorrect type in assignment (different base types) actions.c:244:36: expected unsigned int [unsigned] [usertype] <noident> actions.c:244:36: got restricted __be32 [usertype] <noident> actions.c:265:32: warning: cast to restricted __be32 actions.c:265:32: warning: cast to restricted __be32 actions.c:265:32: warning: cast to restricted __be32 actions.c:265:32: warning: cast to restricted __be32 actions.c:265:32: warning: cast to restricted __be32 actions.c:265:32: warning: cast to restricted __be32 actions.c:325:32: warning: cast to restricted __be32 actions.c:325:32: warning: cast to restricted __be32 actions.c:325:32: warning: cast to restricted __be32 actions.c:325:32: warning: cast to restricted __be32 actions.c:325:32: warning: cast to restricted __be32 actions.c:325:32: warning: cast to restricted __be32 actions.c:346:45: warning: incorrect type in assignment (different base types) actions.c:346:45: expected unsigned int [unsigned] [usertype] <noident> actions.c:346:45: got restricted __be32 [usertype] <noident> actions.c:362:32: warning: cast to restricted __be32 actions.c:362:32: warning: cast to restricted __be32 actions.c:362:32: warning: cast to restricted __be32 actions.c:362:32: warning: cast to restricted __be32 actions.c:362:32: warning: cast to restricted __be32 actions.c:362:32: warning: cast to restricted __be32 actions.c:369:45: warning: incorrect type in assignment (different base types) actions.c:369:45: expected unsigned int [unsigned] [usertype] <noident> actions.c:369:45: got restricted __be32 [usertype] <noident> actions.c:386:32: warning: cast to restricted __be32 actions.c:386:32: warning: cast to restricted __be32 actions.c:386:32: warning: cast to restricted __be32 actions.c:386:32: warning: cast to restricted __be32 actions.c:386:32: warning: cast to restricted __be32 actions.c:386:32: warning: cast to restricted __be32 actions.c:393:41: warning: cast to restricted __be32 actions.c:393:41: warning: cast to restricted __be32 actions.c:393:41: warning: cast to restricted __be32 actions.c:393:41: warning: cast to restricted __be32 actions.c:393:41: warning: cast to restricted __be32 actions.c:393:41: warning: cast to restricted __be32 actions.c:396:58: warning: incorrect type in assignment (different base types) actions.c:396:58: expected unsigned int [unsigned] [usertype] <noident> actions.c:396:58: got restricted __be32 [usertype] <noident> actions.c:412:32: warning: cast to restricted __be32 actions.c:412:32: warning: cast to restricted __be32 actions.c:412:32: warning: cast to restricted __be32 actions.c:412:32: warning: cast to restricted __be32 actions.c:412:32: warning: cast to restricted __be32 actions.c:412:32: warning: cast to restricted __be32 actions.c:419:53: warning: incorrect type in assignment (different base types) actions.c:419:53: expected unsigned int [unsigned] [usertype] <noident> actions.c:419:53: got restricted __be32 [usertype] <noident> actions.c:421:41: warning: cast to restricted __be32 actions.c:421:41: warning: cast to restricted __be32 actions.c:421:41: warning: cast to restricted __be32 actions.c:421:41: warning: cast to restricted __be32 actions.c:421:41: warning: cast to restricted __be32 actions.c:421:41: warning: cast to restricted __be32 actions.c:425:53: warning: incorrect type in assignment (different base types) actions.c:425:53: expected unsigned int [unsigned] [usertype] <noident> actions.c:425:53: got restricted __be32 [usertype] <noident> Thanks, Ben. On Tue, Mar 13, 2012 at 12:39:02AM +0100, ravi.ke...@telekom.com wrote: > Attached latest patch after incorporating code review comments. I > will go through code review comments one more time to make sure > nothing is missed. > > Jesse: If you could please review kernel changes it will be helpful. > > I have tested code after changes on CentOS 6.2 and Ubuntu 11.10. > > "make check" and "make distcheck" matches latest git code results. > > Thanks > Ravi > > -----Original Message----- > From: Kerur, Ravi > Sent: Monday, March 12, 2012 1:58 PM > To: Ben Pfaff > Cc: dev@openvswitch.org > Subject: RE: MPLS important comments (was: Re: [ovs-dev] Patch for MPLS) > > Thanks Ben for the review. Please see inline for <rk>, mostly agreeing to > changes, but some requires inputs/clarifications. > > -----Original Message----- > From: Ben Pfaff [mailto:b...@nicira.com] > Sent: Friday, March 09, 2012 11:20 AM > To: Kerur, Ravi > Cc: dev@openvswitch.org > Subject: MPLS important comments (was: Re: [ovs-dev] Patch for MPLS) > > Thank you for the patch! I have some comments. I'm dividing them > into two groups. The first group, in this email, is comments that > point out likely bugs. The second group, which I will send > separately, is comments that point out less important issues. > > I didn't review the kernel code. That will have to wait for Jesse. > > > include/linux/openvswitch.h > --------------------------- > > We don't usually create structs for the arguments when the arguments > are simple types such as a single integer. Instead, just indicate in > the comment on the side the type and in the big comment on "enum > ovs_action_attr" the effect of the action. Actually every new action > needs to be explained in the big comment. > > Your change renumbers OVS_ACTION_ATTR_SAMPLE but we can't do that > because it's part of the ABI. > > <rk> When I started implementation I thought it will be good to store it in a > variable and might have to reuse in some other part of the code. On a second > look it doesn't look like that's the case. I have made necessary changes. > > lib/dpif-netdev.c > ----------------- > > OVS_ACTION_ATTR_SET_MPLS_LABEL takes an entire MPLS LSE as its > argument, and the odp-util.c code parses an entire MPLS LSE (except > the bottom-of-stack bit, which I've commented on elsewhere), but the > dpif-netdev.c code only sets the "label" bits from the LSE into the > packet. The "datapath" version of the code, on the other hand, does > something more complicated (it appears to set all the fields within > the LSE that are nonzero into the packet). This looks very > inconsistent and probably wrong. > > <rk> OVS_ACTION_ATTR_SET_MPLS_LABEL was a misnomer. Changed it to > OVS_ACTION_ATTR_SET_MPLS_LSE. Moreover, userspace code was not tested until > after potential fix was sent out. It's now inline with kernel and rest of the > code base. > > lib/flow.c > ---------- > > This adds some support for 802.1ad but I'd prefer to keep that > separate from MPLS support, so please remove the 802.1ad stuff from > this patch. > > <rk> Done. > > flow_extract() now has code to skip over inner VLAN tags. What's the > rationale for that? It seems unwise to me, because it makes it > impossible for a controller to distinguish a packet with one VLAN tag > from one with a dozen. The implementation is also not correct as far > as I can tell, because it can overrun the end of the packet. > > For the same reason I wonder whether we should really skip over all > the MPLS labels? > > <rk> I don't know of any use-case where a packet can carry more than 2 vlan > tags. Idea is to parse all vlan_tags/mpls_labels such that packet->l3 is > correctly set after the parse. While parsing multiple tags/labels update > flow->vlan_tci and flow->mpls_lse only after parsing first tag/label. If this > is not the right way to do it let me know how you plan to handle this. I will > incorporate it. > > I found the flow_extract() treatment confusing. It skips past all the > MPLS labels, which would imply that we are going to look at packet > data beyond them, but that will in fact never happen (because the > dl_type is always MPLS). We do want to skip the MPLS header so that > we can set the l3 pointer properly. > > <rk> Please see above response. > > flow_is_mpls_label_valid() looks wrong to me, because I think that > the left-shift in computing 'tmp_label' could discard some high 1-bits > that aren't really valid. I would consider writing it as: > return !(mpls_label & htonl(MPLS_LABEL_MASK >> MPLS_LABEL_SHIFT)); > which I think has the desired effect. > > <rk> Fixed this. > > flow_format() doesn't show the "bottom of stack" bit. Should it? (It > looks like the kernel populates it from the packet, so I would expect > so.) > > <rk> Good to have it. Added stack information. > > I have a concern about flow_hash_symmetric_l4(). This function is not > well-documented, but it's intent is that packets in either direction > in a pair of related flows (e.g. the two flows that make up a TCP > connection) will have the same hash. Will two flows related in that > way have the same MPLS LSE? This function should only hash the > mpls_lse if the answer is "yes". > > <rk> Theoretically the answer is "yes" but I am not 100% on it. I would like > to leave it there unless I see it's not needed at all. > > lib/meta-flow.c > --------------- > > I guess that MFF_MPLS_LABEL and MFP_MPLS_TC should have a > prerequisite, because the MPLS label may only be matched if the > Ethernet type indicates that the packet is a MPLS packet (right?). So > I would add an MFP_MPLS and appropriate support for it. > > <rk> Fixed it. > > I think that the definitions in mf_is_value_valid() and mf_get_value() > are contradictory. mf_is_value_valid() insists that the label be in > the least significant 20 bits of value->be32, but mf_get_value() puts > it in the most significant 20 bits. I suggest that both should use > the least significant 20 bits. > > I think that mf_random_value() has the same problem. > > <rk> Code is written with flow->mpls_lse following MPLS format because it is > easier for anyone debugging it. Issue is when a user configures for a match > based on a label it's in lower 20 bits. In mf_set_value, flow->mpls_lse is > updated and it updates according to MPLS format. For nx_put_match, it follows > the spec by putting the label in lower 20bits. mf_is_value_valid is called > from nx_pull_match in which case label is in lower 20bits and hence the > deviation. > > mf_set_value, mf_get_value and mf_random_value follow the same format. I am > bit reluctant to make changes now since it requires complete code changes and > I am not seeing any added value in doing it. > > > lib/nx-match.c > -------------- > > Like flow_format(), I would expect format_mpls_label() to print the > "bottom of stack" bit. Similarly with the parsing code in > parse_odp_actions() and parse_odp_key_attr(). > > format_odp_action() and other code expects that > OVS_ACTION_ATTR_POP_MPLS has an ethertype argument, but > parse_odp_action() doesn't supply one. > > <rk> Fixed it. > > lib/odp-util.h > -------------- > > In parse_odp_action(), the number here should be 16, not 11, in two > places: > + if (!strncmp(s, "copy_mpls_ttl_in", 11)) { > + nl_msg_put_flag(actions, OVS_ACTION_ATTR_COPY_TTL_IN); > + return 11; > + } > > and here it should be 17, not 12, in two places: > + if (!strncmp(s, "copy_mpls_ttl_out", 12)) { > + nl_msg_put_flag(actions, OVS_ACTION_ATTR_COPY_TTL_OUT); > + return 12; > + } > > <rk> Initially it was just "copy_ttl_in/out", later on I changed it to > "copy_mpls_ttl_in/out", but forgot to update it here. Fixed it now. > > lib/ofp-parse.c > --------------- > > In parse_protocol(), there are two entries for "mpls". Only the first > one will have an effect, the second one would need a different name. > > <rk> Agreed. Have changed it i.e mpls -> unicast, mplsm -> multicast > > lib/ofp-print.c > --------------- > > In ofp_print_action(), please put "0x" into the following formats. > Otherwise, the values printed will be parsed as decimal if they are > fed back into the parser: > + case OFPUTIL_NXAST_PUSH_MPLS: > + nampush = (const struct nx_action_push_mpls *) a; > + ds_put_format(s, "push_mpls:%"PRIx16, ntohs(nampush->ethertype)); > + break; > + > + case OFPUTIL_NXAST_POP_MPLS: > + nampop = (const struct nx_action_pop_mpls *) a; > + ds_put_format(s, "pop_mpls:%"PRIx16, ntohs(nampop->ethertype)); > + break; > > <rk> Fixed. > > > In ofp_match_to_string(), I don't think it's a good idea to abbreviate > both MPLS ethertypes the same way. Otherwise, the shorthand loses > information. > > <rk> Fixed. > > > lib/packets.c > ------------- > > dec_mpls_ttl() will decrement a ttl of 0 to 255. Is that acceptable > behavior? Perhaps the comment should mention it. > > copy_mpls_ttl_in() and copy_mpls_ttl_out() assume that the l3 header > is present and that it is IPv4, or alternatively that an inner MPLS > header is present, without checking. > > set_mpls_lse_tc() is buggy. It needs to do the shift before the mask. > > set_mps_lse_stack() is buggy the same way. > > push_mpls() reads the IP header without first checking that it is > present. > > <rk> As mentioned earlier, userspace was not tested at all until last week. > Taken care of it after unit-testing. > > It appears that push_mpls() refuses to add an MPLS header if there is > a VLAN tag and the inner Ethertype is not IPv4. Why? > > <rk> I didn't think any other L3 protocol would fit into the use-case. For > IPV6, it has its own label and I am not sure there would be a case for > <VLAN/IPV6> packet to push a new MPLS label. Make sense? Or are you referring > to other L3 protocol aka IPX...? > > ofproto/ofproto-dpif.c > ---------------------- > > Did you carefully work out how the actions are implemented? Does the > right thing happen (a no-op) if an OpenFlow flow has a "push mpls" > action followed by a "pop mpls" action? etc. > > <rk> I don't think push_mpls followed by pop_mpls as a nop is a valid use > case. However, pop_mpls followed by push_mpls is a valid use case for label > swap. I have tested code for both scenarios with latest code and it works > fine. > > I'm not sure, in fact, that it makes sense to try to delay committing > MPLS actions. It seems tricky, to me, at least. I'd be tempted to > write them to the ODP actions immediately rather than trying to defer > it. The code would be simpler and more obviously correct, at any rate. > > <rk> When I started off implementation I wanted to take similar approach of > the existing code since there is nothing special in MPLS. Is there a specific > reason why existing code does it? I have made necessary changes not to delay > mpls actions. > > > tests/test-mpls.c > ----------------- > > I don't understand why this program is here. You should be able to > write unit tests for this feature without actually opening raw > sockets, etc. We have sufficient tools to test packets through the > "dummy" interfaces, which some of the existing unit tests. At any > rate I believe that this test program requires "root" privileges to > work. > > <rk> test-mpls.c is the main unit-test function I have used for all mpls and > regression testing. For "root" privileges, I believe even "make install" or > "make check" requires it, so I am not sure why this is a special case? > > You didn't add any unit tests, just this test program. That means > that "make check" doesn't actually test anything MPLS related. We > need at least basic unit tests. > > <rk> I will add unit-test cases for mpls. Since I need to do this for vlan > qinq as well, I would like to combine them and send it as a separate patch. > > <rk> Now, a request. It's really hard to carry around this huge change for a > long time, because everytime I merge I see conflict in different areas of > code and have to retest it each time. If you could let me push the modified > code(I will send out updated patch shortly) into targeted release it would > really help me. I will work on unit-tests shortly after the push and get back > to you at the earliest. I have made sure "make check" matches latest code in > master. Since new code is not breaking existing functionality it would really > help me if it finds a home. > > Thanks, > Ravi > > Thanks, > > Ben. _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev