Ask is moving to Stack Overflow and Serverfault.com! Please use the "opendaylight" tag on either of these sites. This site is now in Read-Only mode

0

Install openflow rule with arbitrary bitmask match on IP address

asked 2017-08-19 08:52:30 -0800

VincentJahjah gravatar image

updated 2017-08-19 09:07:11 -0800

I want to install an openflow rule which matches, for example, all packets with source IP address 0.0.0.1/0.0.0.3, meaning only the 2 last bits of the IP address will be matched, and those last two bits must be '01' respectively. My goal is to make a simple hashing function to spread packets semi-randomly across multiple paths, for load-balancing purposes.

This appears to be supported by OpenFlow 1.1+ at the very least, and should be supported by the OVSwitch that my Mininet uses (version 2.4.0, according to ovs-vsctl -V), but I am not too sure about the OpenFlow version (OpenFlow versions 0x1:0x4, according to ovs-ofctl -V)

I am trying to install flows like I described above, and this is the gist of my code:

int significantBitsMask = (int) (Math.pow(2, powerOfTwo) - 1);
    Ipv4MatchArbitraryBitMaskBuilder ipv4MatchBuilder = new Ipv4MatchArbitraryBitMaskBuilder()
        .setIpv4SourceAddressNoMask(         new Ipv4Address("0.0.0." + String.valueOf(i)))
        .setIpv4SourceArbitraryBitmask(      new DottedQuad( "0.0.0." + String.valueOf(significantBitsMask)))
        .setIpv4DestinationAddressNoMask(    new Ipv4Address("0.0.0.0"))  // Irrelevant
        .setIpv4DestinationArbitraryBitmask( new DottedQuad( "0.0.0.0")); // Irrelevant

        Match match = new MatchBuilder().setLayer3Match(ipv4MatchBuilder.build()).setInPort(srcPort).build();
        ipv4Flow.setMatch(match);

I'm positive that the other sections are not posing any problem, because the rest of the flow definition is reused by other flow installation procedures.

This is my LOG containing the flow installation detail as well as the error that happens when I try to install the flow:

... | Adding flow at openflow:1, name hashingFlow, dest-port Uri [_value=openflow:1:5], cookie 4a00000000000002, ipMask DottedQuad [_value=0.0.0.3]

... | Error installing flow cookie: 4a00000000000002, error: [RpcError [message=Device reported error type BADMATCH code BADPREREQ, severity=ERROR, errorType=APPLICATION, tag=operation-failed, applicationTag=null, info=null, cause=org.opendaylight.openflowjava.protocol.api.connection.DeviceRequestFailedException: Device-side failure]]

It appears that I have entered something wrong somewhere, judging by the name of the errors. That said, I couldn't find anything explaining what was going wrong. Could I be using a wrong OVS version, or a wrong OF version? Am I filling the fields incorrectly?

The code from OpenFlowPlugin seems to contain considerations for Arbitrary bitmask making, and an article from Brocade suggest that this is feasible.

I have also tried the following command (in mininet) to make sure the newer versions of OpenFlow were enabled:

s1 ovs-vsctl set bridge \s1  protocols=OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13

So what am I doing wrong?

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2017-08-21 10:32:12 -0800

VincentJahjah gravatar image

Answering my own question.

I searched for hints of the "prerequisites" that were missing online, and found some scattered across the web, such as here.

In brief, the problem is simply that in an IPV4 match (and probably other higher-level protocol matches), an ethertype match is required to be included. Because I had not added an "EthernetMatch", OpenFlow was not happy. The following code works:

int significantBitsMask = (int) (Math.pow(2, powerOfTwo) - 1);
EthernetMatchBuilder ethernetMatchBuilder = new EthernetMatchBuilder().setEthernetType(
        new EthernetTypeBuilder().setType(new EtherType(Long.valueOf(IPV4_ETHERTYPE))).build());
Ipv4MatchArbitraryBitMaskBuilder ipv4mb = new Ipv4MatchArbitraryBitMaskBuilder()
        .setIpv4SourceAddressNoMask(    new Ipv4Address("0.0.0." + String.valueOf(i)))
        .setIpv4SourceArbitraryBitmask( new DottedQuad( "0.0.0." + String.valueOf(significantBitsMask)));

Match match = new MatchBuilder().setEthernetMatch(ethernetMatchBuilder.build())
                                .setLayer3Match(ipv4mb.build()).setInPort(srcPort).build();
ipv4Flow.setMatch(match);

I can see the arbitrary bitmask matching rules using mininet

s1 ovs-ofctl dump-flows \s1

Giving the following, which is exactly what I wanted:

cookie=0x4a00000000000000, duration=109.041s, table=0, n_packets=0, n_bytes=0, idle_age=109, priority=4,ip,in_port=1,nw_src=0.0.0.0/0.0.0.3 actions=output:7
cookie=0x4a00000000000001, duration=108.722s, table=0, n_packets=0, n_bytes=0, idle_age=108, priority=4,ip,in_port=1,nw_src=0.0.0.1/0.0.0.3 actions=output:8
cookie=0x4a00000000000002, duration=108.220s, table=0, n_packets=0, n_bytes=0, idle_age=108, priority=4,ip,in_port=1,nw_src=0.0.0.2/0.0.0.3 actions=output:5
cookie=0x4a00000000000003, duration=107.719s, table=0, n_packets=0, n_bytes=0, idle_age=107, priority=4,ip,in_port=1,nw_src=0.0.0.3/0.0.0.3 actions=output:6

Now, I don't know where the "prerequistes" related to the "BADPREREQ" errors are defined, which is a bit annoying, but that at least this solves my problem. Interestingly, "BADPREREQ" was an error code added to "BADMATCH" since OpenFlow 1.2+, which means OpenFlow did not always warn the user, or it did not always treat this as an error, and so on. This also confirms that my ovs-switch was indeed running OpenFlow 1.2, which is as expected according to the support specification of ovs 2.4.0.

edit flag offensive delete publish link more
Login/Signup to Answer

Question Tools

Follow
1 follower

Stats

Asked: 2017-08-19 08:52:30 -0800

Seen: 32 times

Last updated: Aug 21