package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
-import java.util.Map;
import java.util.Set;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
-import org.opendaylight.groupbasedpolicy.resolver.EgKey;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Manage the table that enforces port security
- * @author readams
+ *
*/
public class PortSecurity extends FlowTable {
protected static final Logger LOG =
LoggerFactory.getLogger(PortSecurity.class);
- public static final short TABLE_ID = 0;
+ public static short TABLE_ID;
- public PortSecurity(OfTable.OfTableCtx ctx) {
+ public PortSecurity(OfContext ctx, short tableId) {
super(ctx);
+ this.TABLE_ID=tableId;
}
@Override
}
@Override
- public void sync(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- NodeId nodeId, PolicyInfo policyInfo, Dirty dirty) {
- // Allow traffic from tunnel and external ports
- NodeConnectorId tunnelIf = ctx.switchManager.getTunnelPort(nodeId);
+ public void sync(NodeId nodeId, PolicyInfo policyInfo, OfWriter ofWriter) {
+
+ // Allow traffic from tunnel ports
+ NodeConnectorId tunnelIf = ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlan.class);
if (tunnelIf != null)
- allowFromPort(t, tiid, flowMap, tunnelIf);
+ ofWriter.writeFlow(nodeId, TABLE_ID, allowFromPort(tunnelIf));
+
+ // Allow traffic from tunnel ports
+ //TODO Bug 3546 - Difficult: External port is unrelated to Tenant, L3C, L2BD..
+
Set<NodeConnectorId> external =
- ctx.switchManager.getExternalPorts(nodeId);
- for (NodeConnectorId extIf: external) {
- allowFromPort(t, tiid, flowMap, extIf);
+ ctx.getSwitchManager().getExternalPorts(nodeId);
+ for (NodeConnectorId extIf : external) {
+ ofWriter.writeFlow(nodeId, TABLE_ID, allowFromExternalPort(extIf));
}
// Default drop all
- dropFlow(t, tiid, flowMap, 1, null);
+ ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
// Drop IP traffic that doesn't match a source IP rule
- dropFlow(t, tiid, flowMap, 110, FlowUtils.ARP);
- dropFlow(t, tiid, flowMap, 111, FlowUtils.IPv4);
- dropFlow(t, tiid, flowMap, 112, FlowUtils.IPv6);
-
- for (EgKey sepg : ctx.epManager.getGroupsForNode(nodeId)) {
- for (Endpoint e : ctx.epManager.getEPsForNode(nodeId, sepg)) {
- OfOverlayContext ofc = e.getAugmentation(OfOverlayContext.class);
- if (ofc != null && ofc.getNodeConnectorId() != null &&
- (ofc.getLocationType() == null ||
- LocationType.Internal.equals(ofc.getLocationType()))) {
- // Allow layer 3 traffic (ARP and IP) with the correct
- // source IP, MAC, and source port
- l3flow(t, tiid, flowMap, e, ofc, 120, false);
- l3flow(t, tiid, flowMap, e, ofc, 121, true);
- l3DhcpDoraFlow(t, tiid, flowMap, e, ofc, 115);
-
- // Allow layer 2 traffic with the correct source MAC and
- // source port (note lower priority than drop IP rules)
- l2flow(t, tiid, flowMap, e, ofc, 100);
- }
+ ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(110), FlowUtils.ARP, TABLE_ID));
+ ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(111), FlowUtils.IPv4, TABLE_ID));
+ ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(112), FlowUtils.IPv6, TABLE_ID));
+
+ for (Endpoint ep : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
+ OfOverlayContext ofc = ep.getAugmentation(OfOverlayContext.class);
+
+ if (ofc != null && ofc.getNodeConnectorId() != null
+ && (ofc.getLocationType() == null || LocationType.Internal.equals(ofc.getLocationType()))) {
+ // Allow layer 3 traffic (ARP and IP) with the correct
+ // source IP, MAC, and source port
+ l3flow(ofWriter, nodeId, ep, ofc, 120, false);
+ l3flow(ofWriter, nodeId, ep, ofc, 121, true);
+ ofWriter.writeFlow(nodeId, TABLE_ID, l3DhcpDoraFlow(ep, ofc, 115));
+
+ // Allow layer 2 traffic with the correct source MAC and
+ // source port (note lower priority than drop IP rules)
+ ofWriter.writeFlow(nodeId, TABLE_ID, l2flow(ep, ofc, 100));
}
}
}
- private void allowFromPort(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- NodeConnectorId port) {
- FlowId flowid = new FlowId(new StringBuilder()
- .append("allow|")
- .append(port.getValue())
- .toString());
- if (visit(flowMap, flowid.getValue())) {
- FlowBuilder flowb = base()
+ private Flow allowFromPort(NodeConnectorId port) {
+ Match match = new MatchBuilder()
+ .setInPort(port)
+ .build();
+ FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "allow", match);
+ FlowBuilder flowb = base()
.setId(flowid)
.setPriority(Integer.valueOf(200))
- .setMatch(new MatchBuilder()
- .setInPort(port)
- .build())
- .setInstructions(FlowUtils.gotoTableInstructions((short)(getTableId()+1)));
- writeFlow(t, tiid, flowb.build());
- }
+ .setMatch(match)
+ .setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER()));
+ return flowb.build();
}
- private void l2flow(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- Endpoint e, OfOverlayContext ofc,
- Integer priority) {
- FlowId flowid = new FlowId(new StringBuilder()
- .append(ofc.getNodeConnectorId().getValue())
- .append("|")
- .append(e.getMacAddress().getValue())
- .toString());
- if (visit(flowMap, flowid.getValue())) {
- FlowBuilder flowb = base()
+ private Flow allowFromExternalPort(NodeConnectorId port) {
+ Match match = new MatchBuilder()
+ .setInPort(port)
+ .build();
+ FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "allowExternal", match);
+ FlowBuilder flowb = base()
+ .setId(flowid)
+ .setPriority(Integer.valueOf(200))
+ .setMatch(match)
+ .setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_INGRESS_NAT()));
+ return flowb.build();
+ }
+
+ private Flow l2flow(Endpoint ep, OfOverlayContext ofc, Integer priority) {
+ Match match = new MatchBuilder()
+ .setEthernetMatch(
+ FlowUtils.ethernetMatch(ep.getMacAddress(), null, null))
+ .setInPort(ofc.getNodeConnectorId())
+ .build();
+ FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "L2", match);
+ FlowBuilder flowb = base()
.setPriority(priority)
.setId(flowid)
- .setMatch(new MatchBuilder()
- .setEthernetMatch(FlowUtils.ethernetMatch(e.getMacAddress(),
- null, null))
- .setInPort(ofc.getNodeConnectorId())
- .build())
- .setInstructions(FlowUtils.gotoTableInstructions((short)(TABLE_ID + 1)));
+ .setMatch(match)
+ .setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER()));
- writeFlow(t, tiid, flowb.build());
- }
+ return flowb.build();
}
- private void l3DhcpDoraFlow(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- Endpoint e, OfOverlayContext ofc,
- Integer priority) {
+ private Flow l3DhcpDoraFlow(Endpoint ep, OfOverlayContext ofc, Integer priority) {
- Long etherType= FlowUtils.IPv4;
+ //TODO: Handle IPv6 DORA
+ Long etherType = FlowUtils.IPv4;
// DHCP DORA destination is broadcast
- String ikey="255.255.255.255/32";
- Layer3Match m=new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build();
-
- FlowId flowid = new FlowId(new StringBuilder()
- .append(ofc.getNodeConnectorId().getValue())
- .append("|")
- .append(e.getMacAddress().getValue())
- .append("|dhcp|")
- .append(etherType)
- .toString());
- if (visit(flowMap, flowid.getValue())) {
- Flow flow = base()
- .setPriority(priority)
- .setId(flowid)
- .setMatch(new MatchBuilder()
- .setEthernetMatch(FlowUtils.ethernetMatch(e.getMacAddress(),
- null,
- etherType))
- .setLayer3Match(m)
- .setInPort(ofc.getNodeConnectorId())
- .build())
- .setInstructions(FlowUtils.gotoTableInstructions((short)(TABLE_ID + 1)))
- .build();
+ String ikey = "255.255.255.255/32";
+ Layer3Match m = new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build();
+
+ Match match = new MatchBuilder()
+ .setEthernetMatch(
+ FlowUtils.ethernetMatch(ep.getMacAddress(),
+ null,
+ etherType))
+ .setLayer3Match(m)
+ .setInPort(ofc.getNodeConnectorId())
+ .build();
+ FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "dhcp", match);
+ Flow flow = base()
+ .setPriority(priority)
+ .setId(flowid)
+ .setMatch(match)
+ .setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER()))
+ .build();
- writeFlow(t, tiid, flow);
- }
+ return flow;
}
- private void l3flow(ReadWriteTransaction t,
- InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap,
- Endpoint e, OfOverlayContext ofc,
- Integer priority,
- boolean arp) {
- if (e.getL3Address() == null) return;
- for (L3Address l3 : e.getL3Address()) {
- if (l3.getIpAddress() == null) continue;
+ private void l3flow(OfWriter ofWriter, NodeId nodeId,
+ Endpoint ep, OfOverlayContext ofc,
+ Integer priority, boolean arp) {
+ if (ep.getL3Address() == null)
+ return;
+ for (L3Address l3 : ep.getL3Address()) {
+ if (l3.getIpAddress() == null)
+ continue;
Layer3Match m = null;
Long etherType = null;
String ikey = null;
if (l3.getIpAddress().getIpv4Address() != null) {
- ikey = l3.getIpAddress().getIpv4Address().getValue()+"/32";
+ ikey = l3.getIpAddress().getIpv4Address().getValue() + "/32";
if (arp) {
m = new ArpMatchBuilder()
- .setArpSourceTransportAddress(new Ipv4Prefix(ikey))
- .build();
+ .setArpSourceTransportAddress(new Ipv4Prefix(ikey))
+ .build();
etherType = FlowUtils.ARP;
} else {
m = new Ipv4MatchBuilder()
- .setIpv4Source(new Ipv4Prefix(ikey))
- .build();
+ .setIpv4Source(new Ipv4Prefix(ikey))
+ .build();
etherType = FlowUtils.IPv4;
}
} else if (l3.getIpAddress().getIpv6Address() != null) {
- if (arp) continue;
- ikey = l3.getIpAddress().getIpv6Address().getValue()+"/128";
+ if (arp)
+ continue;
+ ikey = l3.getIpAddress().getIpv6Address().getValue() + "/128";
m = new Ipv6MatchBuilder()
- .setIpv6Source(new Ipv6Prefix(ikey))
- .build();
+ .setIpv6Source(new Ipv6Prefix(ikey))
+ .build();
etherType = FlowUtils.IPv6;
} else {
continue;
}
- FlowId flowid = new FlowId(new StringBuilder()
- .append(ofc.getNodeConnectorId().getValue())
- .append("|")
- .append(e.getMacAddress().getValue())
- .append("|")
- .append(ikey)
- .append("|")
- .append(etherType)
- .toString());
- if (visit(flowMap, flowid.getValue())) {
- Flow flow = base()
+ Match match = new MatchBuilder()
+ .setEthernetMatch(
+ FlowUtils.ethernetMatch(ep.getMacAddress(),
+ null,
+ etherType))
+ .setLayer3Match(m)
+ .setInPort(ofc.getNodeConnectorId())
+ .build();
+ FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "L3", match);
+ Flow flow = base()
.setPriority(priority)
.setId(flowid)
- .setMatch(new MatchBuilder()
- .setEthernetMatch(FlowUtils.ethernetMatch(e.getMacAddress(),
- null,
- etherType))
- .setLayer3Match(m)
- .setInPort(ofc.getNodeConnectorId())
- .build())
- .setInstructions(FlowUtils.gotoTableInstructions((short)(TABLE_ID + 1)))
+ .setMatch(match)
+ .setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER()))
.build();
- writeFlow(t, tiid, flow);
- }
+ ofWriter.writeFlow(nodeId, TABLE_ID,flow);
}
}
}