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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlanGpe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Manage the table that enforces port security
+ * <h1>Manage the table that enforces port security. Initial flows in group-based policy pipeline (table=0)</h1>
+ *
+ * Lower-priority flows are leading flows for all traffic incoming from endpoints associated to gbp classifier.<br>
+ * Created when an {@link Endpoint} is internal and contains {@link OfOverlayContext} augmentation. Several flows of
+ * this kind are produced.
+ *<p>
+ * <i>L2 flow:</i><br>
+ * Priority = 100<br>
+ * Matches:<br>
+ * - in_port, {@link NodeConnectorId}
+ * - dl_src {@link org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress}<br>
+ * Actions:<br>
+ * - {@link GoToTable} SOURCE MAPPER table
+ *<p>
+ * <i>L3 flow:</i><br>
+ * Priority = 120<br>
+ * Matches:<br>
+ * - ip, (ethertype)<br>
+ * - in_port, {@link NodeConnectorId}<br>
+ * - dl_src {@link org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress}<br>
+ * - nw_src (source ip address)<br>
+ * Actions:<br>
+ * - {@link GoToTable} SOURCE MAPPER table
+ *<p>
+ * <i>L3 Arp flow:</i><br>
+ * Priority = 121<br>
+ * Matches:<br>
+ * - arp, (ethertype)<br>
+ * - in_port, {@link NodeConnectorId}<br>
+ * - dl_src {@link org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress}<br>
+ * - arp_spa (arp source transport address)<br>
+ * Actions:<br>
+ * - {@link GoToTable} SOURCE MAPPER table
+ *<p>
+ * <i>L3 Dhcp dora flow:</i><br>
+ * Priority = 115<br>
+ * Matches:<br>
+ * - ip, (ethertype)<br>
+ * - in_port, {@link NodeConnectorId}<br>
+ * - dl_src {@link org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress}<br>
+ * - nw_dst (destination ip address)<br>
+ * Actions:<br>
+ * - {@link GoToTable} SOURCE MAPPER table
+ *<p>
+ * Higher-priority flows providing VLAN support for external networks. Created when node contains external ports
+ *<p>
+ * <i>Allow from external:</i><br>
+ * Priority = 200<br>
+ * Matches:<br>
+ * - in_port, {@link NodeConnectorId}<br>
+ * Actions:<br>
+ * - {@link GoToTable} INGRESS NAT table
+ *<p>
+ * <i>Flow that pops VLAN tag for inbound traffic:</i><br>
+ * Priority = 210<br>
+ * See {@link #popVlanTagsOnExternalPort}
+ *<p>
+ * Highest priority flows used to direct traffic coming from tunnel (SFC). These flows are created always
+ *<p>
+ * <i>Allow from tunnel:</i><br>
+ * Priority = 300<br>
+ * Matches:<br>
+ * - in_port (has to be tunnel port), {@link NodeConnectorId}<br>
+ * Actions:<br>
+ * - {@link GoToTable} SOURCE MAPPER table
*
*/
public class PortSecurity extends FlowTable {
public PortSecurity(OfContext ctx, short tableId) {
super(ctx);
- this.TABLE_ID=tableId;
+ TABLE_ID = tableId;
}
@Override
public void sync(NodeId nodeId, OfWriter ofWriter) {
// Allow traffic from tunnel ports
- NodeConnectorId tunnelIf = ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlan.class);
- if (tunnelIf != null)
- ofWriter.writeFlow(nodeId, TABLE_ID, allowFromPort(tunnelIf));
+ NodeConnectorId vxLanTunnel = ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlan.class);
+ NodeConnectorId vxLanGpeTunnel = ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlanGpe.class);
+ if (vxLanTunnel != null)
+ ofWriter.writeFlow(nodeId, TABLE_ID, allowFromPort(vxLanTunnel));
+ if (vxLanGpeTunnel != null)
+ ofWriter.writeFlow(nodeId, TABLE_ID, allowFromPort(vxLanGpeTunnel));
// Default drop all
- ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
+ ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(1, null, TABLE_ID));
// Drop IP traffic that doesn't match a source IP rule
- 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));
+ ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(110, FlowUtils.ARP, TABLE_ID));
+ ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(111, FlowUtils.IPv4, TABLE_ID));
+ ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(112, FlowUtils.IPv6, TABLE_ID));
Set<TenantId> tenantIds = new HashSet<>();
for (Endpoint ep : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
for (NodeConnectorId nc : ctx.getSwitchManager().getExternalPorts(nodeId)) {
// TODO Bug 3546 - Difficult: External port is unrelated to Tenant, L3C, L2BD..
for (Flow flow : popVlanTagsOnExternalPort(nc, tenantId, 210)) {
- // tagged frames have to be untagged when entering policy domain
+ // Tagged frames have to be untagged when entering policy domain
ofWriter.writeFlow(nodeId, TABLE_ID, flow);
}
- // allowing untagged frames entering policy domain
+ // Allowing untagged frames entering policy domain
ofWriter.writeFlow(nodeId, TABLE_ID, allowFromExternalPort(nc, 200));
}
}
FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "allow", match);
FlowBuilder flowb = base()
.setId(flowid)
- .setPriority(Integer.valueOf(300))
+ .setPriority(300)
.setMatch(match)
.setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER()));
return flowb.build();
.setInPort(ofc.getNodeConnectorId())
.build();
FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "dhcp", match);
- Flow flow = base()
+ return base()
.setPriority(priority)
.setId(flowid)
.setMatch(match)
.setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER()))
.build();
- return flow;
}
private void l3flow(OfWriter ofWriter, NodeId nodeId,
for (L3Address l3 : ep.getL3Address()) {
if (l3.getIpAddress() == null)
continue;
- Layer3Match m = null;
- Long etherType = null;
- String ikey = null;
+ Layer3Match m;
+ Long etherType;
+ String ikey;
if (l3.getIpAddress().getIpv4Address() != null) {
ikey = l3.getIpAddress().getIpv4Address().getValue() + "/32";
if (arp) {
Match match = new MatchBuilder().setInPort(nc).build();
FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "allowExternal", match);
FlowBuilder flowb = base().setId(flowid)
- .setPriority(Integer.valueOf(priority))
+ .setPriority(priority)
.setMatch(match)
.setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_INGRESS_NAT()));
return flowb.build();
*/
private List<Flow> popVlanTagsOnExternalPort(NodeConnectorId nc, TenantId tenantId, Integer priority) {
List<Flow> flows = new ArrayList<>();
- for(L2FloodDomain l2Fd : ctx.getTenant(tenantId).getTenant().getForwardingContext().getL2FloodDomain()) {
- Segmentation segmentation = l2Fd.getAugmentation(Segmentation.class);
- if (segmentation != null) {
- Integer vlanId = segmentation.getSegmentationId();
- flows.add(buildPopVlanFlow(nc, vlanId, priority));
+ if(ctx.getTenant(tenantId) != null) {
+ for (L2FloodDomain l2Fd : ctx.getTenant(tenantId).getTenant().getForwardingContext().getL2FloodDomain()) {
+ Segmentation segmentation = l2Fd.getAugmentation(Segmentation.class);
+ if (segmentation != null) {
+ Integer vlanId = segmentation.getSegmentationId();
+ flows.add(buildPopVlanFlow(nc, vlanId, priority));
+ }
}
}
return flows;