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;
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;
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));
}
--- /dev/null
+/*
+ * 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;
+ }
+}
}
}
+ 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;
case default-gateway-extended-community-case {
uses default-gateway-extended-community;
}
+ case layer-2-attributes-extended-community-case {
+ uses layer-2-attributes-extended-community;
+ }
}
}
}
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
--- /dev/null
+/*
+ * 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