2 * Copyright (c) 2017 Cisco Systems. 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.vpp.dhcp;
11 import static org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory.getVppRendererConfig;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.List;
17 import java.util.stream.Stream;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.DhcpRelayCommand;
22 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction;
23 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;
24 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
25 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
26 import org.opendaylight.groupbasedpolicy.util.NetUtils;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.has.subnet.Subnet;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425._interface.attributes._interface.type.choice.TapCase;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.dhcp.rev170315.Ipv4;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.dhcp.rev170315.relay.attributes.ServerBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.dhcp.rev170315.relay.attributes.ServerKey;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 import com.google.common.base.Optional;
40 import com.google.common.collect.SetMultimap;
42 public class DhcpRelayHandler {
44 private static final Logger LOG = LoggerFactory.getLogger(DhcpRelayHandler.class);
45 private final DataBroker dataBroker;
47 public DhcpRelayHandler(DataBroker dataBroker) {
48 this.dataBroker = dataBroker;
51 public List<DhcpRelayCommand> getCreatedIpv4DhcpRelays(long vni_vrfid, Subnet subnet,
52 SetMultimap<String, NodeId> vppNodesByL2Fd) {
53 List<DhcpRelayCommand> dhcpRelayCommandsCreated = new ArrayList<>();
54 if (subnet.getDefaultSubnetGatewayIp() == null) {
55 return dhcpRelayCommandsCreated;
58 for (String bd : vppNodesByL2Fd.keySet()) {
59 Set<NodeId> vppNodes = vppNodesByL2Fd.get(bd);
60 for (NodeId vppNode : vppNodes) {
61 IpAddress ipAddress = resolveDhcpIpAddress(vppNode, subnet);
62 if (ipAddress != null) {
63 dhcpRelayCommandsCreated.add(
64 getDhcpRelayBuilder(vni_vrfid, subnet, ipAddress, General.Operations.PUT, vppNode).build());
69 return dhcpRelayCommandsCreated;
72 private DhcpRelayCommand.DhcpRelayBuilder getDhcpRelayBuilder(long vni_vrfid, Subnet subnet, IpAddress ipAddress,
73 General.Operations operations, NodeId nodeId) {
74 return DhcpRelayCommand.builder()
76 .setRxVrfId(vni_vrfid)
77 .setOperation(operations)
78 .setAddressType(Ipv4.class)
79 .setGatewayIpAddress(subnet.getDefaultSubnetGatewayIp())
80 .setServerIpAddresses(Collections.singletonList(
82 .setAddress(ipAddress)
84 .setKey(new ServerKey(ipAddress, vni_vrfid))
88 private IpAddress resolveDhcpIpAddress(NodeId vppNode, Subnet subnet) {
89 Optional<Config> vppEndpointOptional =
90 DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, getVppRendererConfig(),
91 dataBroker.newReadOnlyTransaction());
93 if (vppEndpointOptional.isPresent() && !vppEndpointOptional.get().getVppEndpoint().isEmpty()) {
94 Stream<VppEndpoint> vppEndpointStream = vppEndpointOptional.get().getVppEndpoint().stream()
95 .filter(vppEndpoint -> vppEndpoint.getInterfaceTypeChoice() instanceof TapCase)
96 .filter(vppEndpoint -> vppEndpoint.getVppNodeId().equals(vppNode))
97 .filter(vppEndpoint -> ((TapCase) vppEndpoint.getInterfaceTypeChoice()).getDhcpServerAddress() != null)
98 .filter(vppEndpoint -> NetUtils.isInRange(subnet.getIpPrefix(), ((TapCase) vppEndpoint
99 .getInterfaceTypeChoice()).getDhcpServerAddress().getIpv4Address().getValue()));
100 java.util.Optional<VppEndpoint> vppEpOptional = vppEndpointStream.findFirst();
101 if (vppEpOptional.isPresent()) {
102 IpAddress dhcpServerAddress =
103 ((TapCase) vppEpOptional.get().getInterfaceTypeChoice()).getDhcpServerAddress();
104 LOG.trace("Found Dhcp server: {} on VPP node: {}", dhcpServerAddress, vppNode);
105 return dhcpServerAddress;
107 LOG.trace("Dhcp server ip not found in subnet: {}, for node: {},in VPP endpoints: {}",
108 subnet, vppNode, vppEndpointOptional.get().getVppEndpoint());
114 public List<DhcpRelayCommand> getDeletedIpv4DhcpRelays(long vni_vrfid, Subnet subnet,
115 SetMultimap<String, NodeId> vppNodesByL2Fd) {
116 if (subnet.getDefaultSubnetGatewayIp() == null) {
117 return new ArrayList<>();
119 List<DhcpRelayCommand> dhcpRelayCommandsDeleted = new ArrayList<>();
122 for (String bd : vppNodesByL2Fd.keySet()) {
123 Set<NodeId> vppNodes = vppNodesByL2Fd.get(bd);
124 for (NodeId vppNode : vppNodes) {
125 IpAddress ipAddress = resolveDhcpIpAddress(vppNode, subnet);
126 if (ipAddress != null) {
127 dhcpRelayCommandsDeleted.add(
128 getDhcpRelayBuilder(vni_vrfid, subnet, ipAddress, General.Operations.DELETE, vppNode).build());
133 return dhcpRelayCommandsDeleted;
136 public boolean submitDhcpRelay(DhcpRelayCommand dhcpRelayCommand) {
137 LOG.trace("Submitting DhcpRelay command: {}, nodeId: {}", dhcpRelayCommand, dhcpRelayCommand.getVppNodeId());
138 switch (dhcpRelayCommand.getOperation()){
140 return GbpNetconfTransaction.netconfSyncedWrite(
141 VppIidFactory.getNetconfNodeIid(dhcpRelayCommand.getVppNodeId()), dhcpRelayCommand,
142 GbpNetconfTransaction.RETRY_COUNT);
144 return GbpNetconfTransaction.netconfSyncedDelete(
145 VppIidFactory.getNetconfNodeIid(dhcpRelayCommand.getVppNodeId()), dhcpRelayCommand,
146 GbpNetconfTransaction.RETRY_COUNT);
148 return GbpNetconfTransaction.netconfSyncedMerge(
149 VppIidFactory.getNetconfNodeIid(dhcpRelayCommand.getVppNodeId()), dhcpRelayCommand,
150 GbpNetconfTransaction.RETRY_COUNT);
152 LOG.warn("Unknown operation for command, cannot submit command {}.", dhcpRelayCommand);