BUG-5440: VWPS EVPN Extension 69/37869/5
authorClaudio D. Gasparini <cgaspari@cisco.com>
Wed, 20 Apr 2016 11:28:50 +0000 (13:28 +0200)
committerMilos Fabian <milfabia@cisco.com>
Thu, 21 Apr 2016 11:49:51 +0000 (11:49 +0000)
VWPS EVPN Extension implementation
ref: https://tools.ietf.org/html/draft-ietf-bess-evpn-vpws-02#section-3.1

Change-Id: Idff5cd22853cd94505468280c2d601f6da111e37
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/BGPActivator.java
bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/extended/communities/Layer2AttributesExtCom.java [new file with mode: 0644]
bgp/evpn/src/main/yang/bgp-evpn.yang
bgp/evpn/src/test/java/org/opendaylight/protocol/bgp/evpn/impl/extended/communities/Layer2AttributesExtComTest.java [new file with mode: 0644]

index 8ebe42514551df0ec0f60bf95b8d17c5c07bda0f..5fbdda8ece01dc936c494fdfebe326c6ff18b2f9 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.protocol.bgp.evpn.impl.esi.types.ESIActivator;
 import org.opendaylight.protocol.bgp.evpn.impl.extended.communities.DefaultGatewayExtCom;
 import org.opendaylight.protocol.bgp.evpn.impl.extended.communities.ESILabelExtCom;
 import org.opendaylight.protocol.bgp.evpn.impl.extended.communities.ESImpRouteTargetExtCom;
+import org.opendaylight.protocol.bgp.evpn.impl.extended.communities.Layer2AttributesExtCom;
 import org.opendaylight.protocol.bgp.evpn.impl.extended.communities.MACMobExtCom;
 import org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriActivator;
 import org.opendaylight.protocol.bgp.parser.spi.AbstractBGPExtensionProviderActivator;
@@ -21,6 +22,7 @@ import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.EvpnSubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.L2vpnAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.routes.evpn.routes.evpn.route.attributes.extended.communities.extended.community.DefaultGatewayExtendedCommunityCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.routes.evpn.routes.evpn.route.attributes.extended.communities.extended.community.Layer2AttributesExtendedCommunityCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.extended.communities.extended.community.EsImportRouteExtendedCommunityCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.extended.communities.extended.community.EsiLabelExtendedCommunityCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.extended.communities.extended.community.MacMobilityExtendedCommunityCase;
@@ -58,6 +60,10 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
         final MACMobExtCom macEC = new MACMobExtCom();
         regs.add(context.registerExtendedCommunityParser(macEC.getType(true), macEC.getSubType(), macEC));
         regs.add(context.registerExtendedCommunitySerializer(MacMobilityExtendedCommunityCase.class, macEC));
+
+        final Layer2AttributesExtCom l2a = new Layer2AttributesExtCom();
+        regs.add(context.registerExtendedCommunityParser(l2a.getType(false), l2a.getSubType(), l2a));
+        regs.add(context.registerExtendedCommunitySerializer(Layer2AttributesExtendedCommunityCase.class, l2a));
     }
 
 
diff --git a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/extended/communities/Layer2AttributesExtCom.java b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/extended/communities/Layer2AttributesExtCom.java
new file mode 100644 (file)
index 0000000..d0f6b9d
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.evpn.impl.extended.communities;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.util.BitArray;
+import org.opendaylight.protocol.util.ByteBufWriteUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.routes.evpn.routes.evpn.route.attributes.extended.communities.extended.community.Layer2AttributesExtendedCommunityCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.routes.evpn.routes.evpn.route.attributes.extended.communities.extended.community.Layer2AttributesExtendedCommunityCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.layer._2.attributes.extended.community.Layer2AttributesExtendedCommunity;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.layer._2.attributes.extended.community.Layer2AttributesExtendedCommunityBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.ExtendedCommunity;
+
+public class Layer2AttributesExtCom extends AbstractExtendedCommunities {
+    private static final int SUBTYPE = 4; // TODO: TBD BY IANA
+    private static final int FLAGS_SIZE = 16;
+    private static final int PRIMARY_PE_OFFSET = 15;
+    private static final int CONTROL_WORD_OFFSET = 13;
+    private static final int BACKUP_PE_OFFSET = 14;
+    private static final int RESERVED = 2;
+
+    @Override
+    public ExtendedCommunity parseExtendedCommunity(final ByteBuf body) throws BGPDocumentedException, BGPParsingException {
+        final Layer2AttributesExtendedCommunityBuilder builder = new Layer2AttributesExtendedCommunityBuilder();
+        final BitArray flags = BitArray.valueOf(body, FLAGS_SIZE);
+        builder.setPrimaryPe(flags.get(PRIMARY_PE_OFFSET));
+        builder.setBackupPe(flags.get(BACKUP_PE_OFFSET));
+        builder.setControlWord(flags.get(CONTROL_WORD_OFFSET));
+        builder.setL2Mtu(body.readUnsignedShort());
+        body.skipBytes(RESERVED);
+        return new Layer2AttributesExtendedCommunityCaseBuilder().setLayer2AttributesExtendedCommunity(builder.build()).build();
+    }
+
+    @Override
+    public void serializeExtendedCommunity(final ExtendedCommunity extendedCommunity, final ByteBuf body) {
+        Preconditions.checkArgument(extendedCommunity instanceof Layer2AttributesExtendedCommunityCase,
+            "The extended community %s is not EsImportRouteExtendedCommunityCaseCase type.", extendedCommunity);
+        final Layer2AttributesExtendedCommunity extCom = ((Layer2AttributesExtendedCommunityCase) extendedCommunity).getLayer2AttributesExtendedCommunity();
+        final BitArray flags = new BitArray(FLAGS_SIZE);
+        flags.set(PRIMARY_PE_OFFSET, extCom.isPrimaryPe());
+        flags.set(BACKUP_PE_OFFSET, extCom.isBackupPe());
+        flags.set(CONTROL_WORD_OFFSET, extCom.isControlWord());
+        flags.toByteBuf(body);
+        ByteBufWriteUtil.writeUnsignedShort(extCom.getL2Mtu(), body);
+        body.writeZero(RESERVED);
+    }
+
+    @Override
+    public int getSubType() {
+        return SUBTYPE;
+    }
+}
index 61cd376bdafe899c62d7b1542717b3b0418d1029..c9948e4b41ee361602e15b50d82d06ce9f773294 100644 (file)
@@ -343,6 +343,33 @@ module odl-bgp-evpn {
         }
     }
 
+    grouping layer-2-attributes-extended-community {
+        container layer-2-attributes-extended-community {
+            reference "https://tools.ietf.org/html/draft-ietf-bess-evpn-vpws-02#section-3.1";
+            description
+                "The EVPN Layer 2 attributes extended community is a extended community
+                to be included with Ethernet A-D per EVI route.
+                This attribute is mandatory if multihoming is enabled.";
+
+                leaf primary-pe {
+                   type boolean;
+                   default false;
+                }
+                leaf backup-pe {
+                   type boolean;
+                   default false;
+                }
+                leaf control-word {
+                   type boolean;
+                   default false;
+                }
+                leaf l2-mtu {
+                    type uint16;
+                    mandatory true;
+                }
+        }
+    }
+
     grouping evpn-destination {
         list evpn-destination {
             uses evpn;
@@ -371,6 +398,9 @@ module odl-bgp-evpn {
                         case default-gateway-extended-community-case {
                             uses default-gateway-extended-community;
                         }
+                        case layer-2-attributes-extended-community-case {
+                            uses layer-2-attributes-extended-community;
+                        }
                     }
                 }
             }
@@ -473,5 +503,8 @@ module odl-bgp-evpn {
         case default-gateway-extended-community-case {
             uses default-gateway-extended-community;
         }
+        case layer-2-attributes-extended-community-case {
+            uses layer-2-attributes-extended-community;
+        }
     }
 }
\ No newline at end of file
diff --git a/bgp/evpn/src/test/java/org/opendaylight/protocol/bgp/evpn/impl/extended/communities/Layer2AttributesExtComTest.java b/bgp/evpn/src/test/java/org/opendaylight/protocol/bgp/evpn/impl/extended/communities/Layer2AttributesExtComTest.java
new file mode 100644 (file)
index 0000000..d003ba7
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.evpn.impl.extended.communities;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.opendaylight.protocol.bgp.evpn.impl.EvpnTestUtil.COMMUNITY_VALUE_SIZE;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.routes.evpn.routes.evpn.route.attributes.extended.communities.extended.community.DefaultGatewayExtendedCommunityCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.routes.evpn.routes.evpn.route.attributes.extended.communities.extended.community.Layer2AttributesExtendedCommunityCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.routes.evpn.routes.evpn.route.attributes.extended.communities.extended.community.Layer2AttributesExtendedCommunityCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.layer._2.attributes.extended.community.Layer2AttributesExtendedCommunityBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.extended.community.ExtendedCommunity;
+
+public class Layer2AttributesExtComTest {
+    private static final byte[] RESULT = {(byte) 0x00, (byte) 0x07, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00};
+    private Layer2AttributesExtCom parser;
+
+    @Before
+    public void setUp() {
+        this.parser = new Layer2AttributesExtCom();
+    }
+
+    @Test
+    public void parserTest() throws BGPParsingException, BGPDocumentedException {
+        final ByteBuf buff = Unpooled.buffer(COMMUNITY_VALUE_SIZE);
+
+        final Layer2AttributesExtendedCommunityCase expected = new Layer2AttributesExtendedCommunityCaseBuilder().setLayer2AttributesExtendedCommunity(
+            new Layer2AttributesExtendedCommunityBuilder().setBackupPe(true).setControlWord(true).setPrimaryPe(true).setL2Mtu(257).build()).build();
+        this.parser.serializeExtendedCommunity(expected, buff);
+        assertArrayEquals(RESULT, ByteArray.getAllBytes(buff));
+
+        final ExtendedCommunity result = this.parser.parseExtendedCommunity(Unpooled.wrappedBuffer(RESULT));
+        assertEquals(expected, result);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void wrongCaseTest() {
+        this.parser.serializeExtendedCommunity(new DefaultGatewayExtendedCommunityCaseBuilder().build(), null);
+    }
+
+    @Test
+    public void testSubtype() {
+        assertEquals(4, this.parser.getSubType());
+    }
+}
\ No newline at end of file