2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
14 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
15 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
16 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
17 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
18 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
41 * Manage the table that enforces port security
44 public class PortSecurity extends FlowTable {
45 protected static final Logger LOG =
46 LoggerFactory.getLogger(PortSecurity.class);
48 public static final short TABLE_ID = 0;
50 public PortSecurity(OfContext ctx) {
55 public short getTableId() {
60 public void sync(ReadWriteTransaction t,
61 InstanceIdentifier<Table> tiid,
62 Map<String, FlowCtx> flowMap,
63 NodeId nodeId, PolicyInfo policyInfo, Dirty dirty) {
64 // Allow traffic from tunnel and external ports
65 NodeConnectorId tunnelIf = ctx.getSwitchManager().getTunnelPort(nodeId);
67 allowFromPort(t, tiid, flowMap, tunnelIf);
68 Set<NodeConnectorId> external =
69 ctx.getSwitchManager().getExternalPorts(nodeId);
70 for (NodeConnectorId extIf: external) {
71 allowFromPort(t, tiid, flowMap, extIf);
75 dropFlow(t, tiid, flowMap, 1, null);
77 // Drop IP traffic that doesn't match a source IP rule
78 dropFlow(t, tiid, flowMap, 110, FlowUtils.ARP);
79 dropFlow(t, tiid, flowMap, 111, FlowUtils.IPv4);
80 dropFlow(t, tiid, flowMap, 112, FlowUtils.IPv6);
82 for (EgKey sepg : ctx.getEndpointManager().getGroupsForNode(nodeId)) {
83 for (Endpoint e : ctx.getEndpointManager().getEPsForNode(nodeId, sepg)) {
84 OfOverlayContext ofc = e.getAugmentation(OfOverlayContext.class);
85 if (ofc != null && ofc.getNodeConnectorId() != null &&
86 (ofc.getLocationType() == null ||
87 LocationType.Internal.equals(ofc.getLocationType()))) {
88 // Allow layer 3 traffic (ARP and IP) with the correct
89 // source IP, MAC, and source port
90 l3flow(t, tiid, flowMap, e, ofc, 120, false);
91 l3flow(t, tiid, flowMap, e, ofc, 121, true);
92 l3DhcpDoraFlow(t, tiid, flowMap, e, ofc, 115);
94 // Allow layer 2 traffic with the correct source MAC and
95 // source port (note lower priority than drop IP rules)
96 l2flow(t, tiid, flowMap, e, ofc, 100);
102 private void allowFromPort(ReadWriteTransaction t,
103 InstanceIdentifier<Table> tiid,
104 Map<String, FlowCtx> flowMap,
105 NodeConnectorId port) {
106 FlowId flowid = new FlowId(new StringBuilder()
108 .append(port.getValue())
110 if (visit(flowMap, flowid.getValue())) {
111 FlowBuilder flowb = base()
113 .setPriority(Integer.valueOf(200))
114 .setMatch(new MatchBuilder()
117 .setInstructions(FlowUtils.gotoTableInstructions((short)(getTableId()+1)));
118 writeFlow(t, tiid, flowb.build());
122 private void l2flow(ReadWriteTransaction t,
123 InstanceIdentifier<Table> tiid,
124 Map<String, FlowCtx> flowMap,
125 Endpoint e, OfOverlayContext ofc,
127 FlowId flowid = new FlowId(new StringBuilder()
128 .append(ofc.getNodeConnectorId().getValue())
130 .append(e.getMacAddress().getValue())
132 if (visit(flowMap, flowid.getValue())) {
133 FlowBuilder flowb = base()
134 .setPriority(priority)
136 .setMatch(new MatchBuilder()
137 .setEthernetMatch(FlowUtils.ethernetMatch(e.getMacAddress(),
139 .setInPort(ofc.getNodeConnectorId())
141 .setInstructions(FlowUtils.gotoTableInstructions((short)(TABLE_ID + 1)));
143 writeFlow(t, tiid, flowb.build());
147 private void l3DhcpDoraFlow(ReadWriteTransaction t,
148 InstanceIdentifier<Table> tiid,
149 Map<String, FlowCtx> flowMap,
150 Endpoint e, OfOverlayContext ofc,
153 Long etherType= FlowUtils.IPv4;
154 // DHCP DORA destination is broadcast
155 String ikey="255.255.255.255/32";
156 Layer3Match m=new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build();
158 FlowId flowid = new FlowId(new StringBuilder()
159 .append(ofc.getNodeConnectorId().getValue())
161 .append(e.getMacAddress().getValue())
165 if (visit(flowMap, flowid.getValue())) {
167 .setPriority(priority)
169 .setMatch(new MatchBuilder()
170 .setEthernetMatch(FlowUtils.ethernetMatch(e.getMacAddress(),
174 .setInPort(ofc.getNodeConnectorId())
176 .setInstructions(FlowUtils.gotoTableInstructions((short)(TABLE_ID + 1)))
179 writeFlow(t, tiid, flow);
183 private void l3flow(ReadWriteTransaction t,
184 InstanceIdentifier<Table> tiid,
185 Map<String, FlowCtx> flowMap,
186 Endpoint e, OfOverlayContext ofc,
189 if (e.getL3Address() == null) return;
190 for (L3Address l3 : e.getL3Address()) {
191 if (l3.getIpAddress() == null) continue;
192 Layer3Match m = null;
193 Long etherType = null;
195 if (l3.getIpAddress().getIpv4Address() != null) {
196 ikey = l3.getIpAddress().getIpv4Address().getValue()+"/32";
198 m = new ArpMatchBuilder()
199 .setArpSourceTransportAddress(new Ipv4Prefix(ikey))
201 etherType = FlowUtils.ARP;
203 m = new Ipv4MatchBuilder()
204 .setIpv4Source(new Ipv4Prefix(ikey))
206 etherType = FlowUtils.IPv4;
208 } else if (l3.getIpAddress().getIpv6Address() != null) {
210 ikey = l3.getIpAddress().getIpv6Address().getValue()+"/128";
211 m = new Ipv6MatchBuilder()
212 .setIpv6Source(new Ipv6Prefix(ikey))
214 etherType = FlowUtils.IPv6;
218 FlowId flowid = new FlowId(new StringBuilder()
219 .append(ofc.getNodeConnectorId().getValue())
221 .append(e.getMacAddress().getValue())
227 if (visit(flowMap, flowid.getValue())) {
229 .setPriority(priority)
231 .setMatch(new MatchBuilder()
232 .setEthernetMatch(FlowUtils.ethernetMatch(e.getMacAddress(),
236 .setInPort(ofc.getNodeConnectorId())
238 .setInstructions(FlowUtils.gotoTableInstructions((short)(TABLE_ID + 1)))
241 writeFlow(t, tiid, flow);