package net.onrc.onos.apps.segmentrouting; import java.io.IOException; import java.util.ArrayList; import java.util.List; import net.floodlightcontroller.core.IOF13Switch; import net.onrc.onos.apps.segmentrouting.SegmentRoutingTunnel.TunnelRouteInfo; import net.onrc.onos.core.matchaction.MatchAction; import net.onrc.onos.core.matchaction.MatchActionId; import net.onrc.onos.core.matchaction.MatchActionOperationEntry; import net.onrc.onos.core.matchaction.MatchActionOperations.Operator; import net.onrc.onos.core.matchaction.action.Action; import net.onrc.onos.core.matchaction.action.DecNwTtlAction; import net.onrc.onos.core.matchaction.action.GroupAction; import net.onrc.onos.core.matchaction.action.OutputAction; import net.onrc.onos.core.matchaction.action.SetDAAction; import net.onrc.onos.core.matchaction.action.SetSAAction; import net.onrc.onos.core.matchaction.match.PacketMatch; import net.onrc.onos.core.topology.Switch; import net.onrc.onos.core.util.Dpid; import net.onrc.onos.core.util.PortNumber; import net.onrc.onos.core.util.SwitchPort; import org.projectfloodlight.openflow.types.MacAddress; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.esotericsoftware.minlog.Log; public class SegmentRoutingPolicyTunnel extends SegmentRoutingPolicy { private static final Logger log = LoggerFactory .getLogger(SegmentRoutingPolicyTunnel.class); private String tunnelId; public SegmentRoutingPolicyTunnel(SegmentRoutingManager srm, String pid, PolicyType type, PacketMatch match, int priority, String tid) { super(srm, pid, type, match, priority); this.tunnelId = tid; } @Override public boolean createPolicy() { SegmentRoutingTunnel tunnelInfo = srManager.getTunnelInfo(tunnelId); List<TunnelRouteInfo> routes = tunnelInfo.getRoutes(); for (TunnelRouteInfo route : routes) { List<Action> actions = new ArrayList<>(); // Check PHP was done by stitching // If no MPLS label is added, then NW TTL needs to be decremented if (route.getRoute().isEmpty()) { DecNwTtlAction decNwTtlAction = new DecNwTtlAction(1); actions.add(decNwTtlAction); Switch srcSw = srManager.getSwitch(route.getSrcSwDpid()); Switch destSwitch = srManager.getSwitch(route.getFwdSwDpid().get(0).toString()); MacAddress srcMac = MacAddress.of(srcSw.getStringAttribute("routerMac")); MacAddress dstMac = MacAddress.of(destSwitch.getStringAttribute("routerMac")); SetSAAction setSAAction = new SetSAAction(srcMac); SetDAAction setDAAction = new SetDAAction(dstMac); actions.add(setSAAction); actions.add(setDAAction); List<String> fwdSwDpids = new ArrayList<String>(); for (Dpid dpid: route.getFwdSwDpid()) { fwdSwDpids.add(dpid.toString()); } PortNumber port = srManager.pickOnePort(srcSw, fwdSwDpids); OutputAction outputAction = new OutputAction(port); actions.add(outputAction); } else { GroupAction groupAction = new GroupAction(); groupAction.setGroupId(route.getGroupId()); actions.add(groupAction); } MatchAction matchAction = new MatchAction(new MatchActionId( srManager.getNextMatchActionID()), new SwitchPort((long) 0, (short) 0), match, priority, actions); MatchActionOperationEntry maEntry = new MatchActionOperationEntry(Operator.ADD, matchAction); IOF13Switch sw13 = srManager.getIOF13Switch(route.getSrcSwDpid()); if (sw13 != null) { srManager.printMatchActionOperationEntry(sw13, maEntry); try { sw13.pushFlow(maEntry); } catch (IOException e) { e.printStackTrace(); return false; } } else { Log.warn("Cannot find the target switch {}", route.getSrcSwDpid()); return false; } } return true; } @Override public boolean removePolicy() { List<Action> actions = new ArrayList<>(); int gropuId = 0; // dummy group ID GroupAction groupAction = new GroupAction(); groupAction.setGroupId(gropuId); actions.add(groupAction); MatchAction matchAction = new MatchAction(new MatchActionId( srManager.getNextMatchActionID()), new SwitchPort((long) 0, (short) 0), match, priority, actions); MatchActionOperationEntry maEntry = new MatchActionOperationEntry(Operator.REMOVE, matchAction); SegmentRoutingTunnel tunnel = srManager.getTunnelInfo(tunnelId); if (tunnel == null) { log.warn("Cannot find the tunnel {} for the policy {}", tunnelId, policyId); return false; } List<TunnelRouteInfo> routes = tunnel.getRoutes(); for (TunnelRouteInfo route : routes) { IOF13Switch sw13 = srManager.getIOF13Switch(route.getSrcSwDpid()); if (sw13 == null) { log.warn("Cannt find the switch {}", route.getSrcSwDpid()); return false; } else { srManager.printMatchActionOperationEntry(sw13, maEntry); try { sw13.pushFlow(maEntry); } catch (IOException e) { e.printStackTrace(); log.debug("policy remove failed due to pushFlow() exception"); return false; } } } return true; } /** * Get the Tunnel ID * @return tunnel ID */ public String getTunnelId(){ return this.tunnelId; } }