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.


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.


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.

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?

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.

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.

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.)

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".


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.

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.


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.


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;
+    }


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.


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;

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.


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.

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?


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.

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.


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.

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.

Thanks,

Ben.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to