1
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
3
// Copyright (c) 2007-2008 International Computer Science Institute
5
// Permission is hereby granted, free of charge, to any person obtaining a
6
// copy of this software and associated documentation files (the "Software")
7
// to deal in the Software without restriction, subject to the conditions
8
// listed in the XORP LICENSE file. These conditions include: you must
9
// preserve this copyright notice, and you cannot mention the copyright
10
// holders in advertising related to the Software without their permission.
11
// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
12
// notice is a summary of the XORP LICENSE file; the license in that file is
15
#ident "$XORP: xorp/fea/data_plane/ifconfig/ifconfig_vlan_get_bsd.cc,v 1.7 2008/01/04 03:16:10 pavlin Exp $"
17
#include "fea/fea_module.h"
19
#include "libxorp/xorp.h"
20
#include "libxorp/xlog.h"
21
#include "libxorp/debug.h"
22
#include "libxorp/ether_compat.h"
24
#include "libcomm/comm_api.h"
26
#ifdef HAVE_SYS_IOCTL_H
27
#include <sys/ioctl.h>
29
#ifdef HAVE_NET_IF_VLAN_VAR_H
30
#include <net/if_vlan_var.h>
32
#ifdef HAVE_NET_IF_VLANVAR_H
33
#include <net/if_vlanvar.h>
35
#ifdef HAVE_NET_VLAN_IF_VLAN_VAR_H
36
#include <net/vlan/if_vlan_var.h>
39
#include "fea/ifconfig.hh"
41
#include "ifconfig_vlan_get_bsd.hh"
45
// Get VLAN information about network interfaces from the underlying system.
47
// The mechanism to obtain the information is BSD-specific ioctl(2).
52
IfConfigVlanGetBsd::IfConfigVlanGetBsd(FeaDataPlaneManager& fea_data_plane_manager)
53
: IfConfigVlanGet(fea_data_plane_manager),
58
IfConfigVlanGetBsd::~IfConfigVlanGetBsd()
62
if (stop(error_msg) != XORP_OK) {
63
XLOG_ERROR("Cannot stop the BSD-specific ioctl(2) mechanism to get "
64
"information about VLAN network interfaces from the "
65
"underlying system: %s",
71
IfConfigVlanGetBsd::start(string& error_msg)
77
_s4 = socket(AF_INET, SOCK_DGRAM, 0);
79
error_msg = c_format("Could not initialize IPv4 ioctl() "
80
"socket: %s", strerror(errno));
81
XLOG_FATAL("%s", error_msg.c_str());
91
IfConfigVlanGetBsd::stop(string& error_msg)
93
int ret_value4 = XORP_OK;
99
ret_value4 = comm_close(_s4);
101
if (ret_value4 != XORP_OK) {
102
error_msg = c_format("Could not close IPv4 ioctl() socket: %s",
103
comm_get_last_error_str());
107
if (ret_value4 != XORP_OK)
116
IfConfigVlanGetBsd::pull_config(IfTree& iftree)
118
return read_config(iftree);
122
IfConfigVlanGetBsd::read_config(IfTree& iftree)
124
IfTree::IfMap::iterator ii;
128
error_msg = c_format("Cannot read VLAN interface intormation: "
129
"the IfConfigVlanGetBsd plugin is not running");
130
XLOG_ERROR("%s", error_msg.c_str());
133
XLOG_ASSERT(_s4 >= 0);
136
// Check all interfaces whether they are actually VLANs.
137
// If an interface is found to be a VLAN, then its vif state is
138
// copied as a vif child to its physical parent interface.
139
// Note that we keep the original VLAN interface state in the IfTree
140
// so the rest of the FEA is not surprised if that state suddenly is
143
for (ii = iftree.interfaces().begin();
144
ii != iftree.interfaces().end();
146
IfTreeInterface* ifp = &ii->second;
147
// Ignore interfaces that are to be deleted
148
if (ifp->is_marked(IfTreeItem::DELETED))
152
struct vlanreq vlanreq;
154
// Test whether a VLAN interface
155
memset(&ifreq, 0, sizeof(ifreq));
156
memset(&vlanreq, 0, sizeof(vlanreq));
157
strncpy(ifreq.ifr_name, ifp->ifname().c_str(),
158
sizeof(ifreq.ifr_name) - 1);
159
ifreq.ifr_data = reinterpret_cast<caddr_t>(&vlanreq);
160
if (ioctl(_s4, SIOCGETVLAN, (caddr_t)&ifreq) < 0)
161
continue; // XXX: Most likely not a VLAN interface
164
// XXX: VLAN interface
167
// Get the VLAN information
168
uint16_t vlan_id = vlanreq.vlr_tag;
169
string parent_ifname = vlanreq.vlr_parent;
171
if (parent_ifname.empty())
174
IfTreeInterface* parent_ifp = iftree.find_interface(parent_ifname);
175
if ((parent_ifp == NULL) || parent_ifp->is_marked(IfTreeItem::DELETED))
178
// Find or add the VLAN vif
179
IfTreeVif* parent_vifp = parent_ifp->find_vif(ifp->ifname());
180
if (parent_vifp == NULL) {
181
parent_ifp->add_vif(ifp->ifname());
182
parent_vifp = parent_ifp->find_vif(ifp->ifname());
184
XLOG_ASSERT(parent_vifp != NULL);
186
// Copy the vif state
187
IfTreeVif* vifp = ifp->find_vif(ifp->ifname());
189
parent_vifp->copy_state(*vifp);
190
parent_vifp->ipv4addrs() = vifp->ipv4addrs();
191
parent_vifp->ipv6addrs() = vifp->ipv6addrs();
194
// Set the VLAN vif info
195
parent_vifp->set_vlan(true);
196
parent_vifp->set_vlan_id(vlan_id);
202
#endif // HAVE_VLAN_BSD