Esempio n. 1
0
void netlink_neigh_info::fill(struct rtnl_neigh* neigh)
{
	if (!neigh) 
		return;

	nl_addr* addr;
	char addr_str[ADDR_MAX_STR_LEN + 1];

	addr = rtnl_neigh_get_dst(neigh);
	if (addr) {
		dst_addr_str = nl_addr2str(addr, addr_str, ADDR_MAX_STR_LEN);
		dst_addr = (unsigned char*)nl_addr_get_binary_addr(addr);
		dst_addr_len = nl_addr_get_len(addr);
	}

	addr = rtnl_neigh_get_lladdr(neigh);
	if (addr) {
		lladdr_str = nl_addr2str(addr, addr_str, ADDR_MAX_STR_LEN);
		lladdr = (unsigned char*)nl_addr_get_binary_addr(addr);
		lladdr_len = nl_addr_get_len(addr);
	}
	//addr_family = rtnl_neigh_get_family(neigh);
	flags = rtnl_neigh_get_flags(neigh);
	ifindex = rtnl_neigh_get_ifindex(neigh);
	state = rtnl_neigh_get_state(neigh);
	type = rtnl_neigh_get_type(neigh);
}
static void
find_one_address (struct nl_object *object, void *user_data)
{
	FindAddrInfo *info = user_data;
	struct rtnl_addr *addr = (struct rtnl_addr *) object;
	struct nl_addr *local;
	void *binaddr;

	if (info->found)
		return;

	if (rtnl_addr_get_ifindex (addr) != info->ifindex)
		return;
	if (rtnl_addr_get_family (addr) != info->family)
		return;

	if (rtnl_addr_get_prefixlen (addr) != info->prefix)
		return;

	local = rtnl_addr_get_local (addr);
	if (nl_addr_get_family (local) != info->family)
		return;
	if (nl_addr_get_len (local) != info->addrlen)
		return;
	binaddr = nl_addr_get_binary_addr (local);
	if (binaddr) {
		if (memcmp (binaddr, info->addr, info->addrlen) == 0)
			info->found = TRUE; /* Yay, found it */
	}
}
Esempio n. 3
0
void nl_bridge::add_neigh_to_fdb(rtnl_neigh *neigh) {
  assert(sw);
  assert(neigh);

  uint32_t port = nl->get_port_id(rtnl_neigh_get_ifindex(neigh));
  if (port == 0) {
    VLOG(1) << __FUNCTION__ << ": unknown port for neigh " << OBJ_CAST(neigh);
    return;
  }

  nl_addr *mac = rtnl_neigh_get_lladdr(neigh);
  int vlan = rtnl_neigh_get_vlan(neigh);

  bool permanent = true;

  // for sure this is master (sw bridged)
  if (rtnl_neigh_get_master(neigh) &&
      !(rtnl_neigh_get_flags(neigh) & NTF_MASTER)) {
    rtnl_neigh_set_flags(neigh, NTF_MASTER);
  }

  // check if entry already exists in cache
  if (is_mac_in_l2_cache(neigh)) {
    permanent = false;
  }

  rofl::caddress_ll _mac((uint8_t *)nl_addr_get_binary_addr(mac),
                         nl_addr_get_len(mac));

  LOG(INFO) << __FUNCTION__ << ": add mac=" << _mac << " to bridge "
            << rtnl_link_get_name(bridge) << " on port=" << port
            << " vlan=" << (unsigned)vlan << ", permanent=" << permanent;
  LOG(INFO) << __FUNCTION__ << ": object: " << OBJ_CAST(neigh);
  sw->l2_addr_add(port, vlan, _mac, true, permanent);
}
Esempio n. 4
0
static Option<net::IP> IP(nl_addr* _ip)
{
  Option<net::IP> result;
  if (_ip != NULL && nl_addr_get_len(_ip) != 0) {
    struct in_addr* addr = (struct in_addr*) nl_addr_get_binary_addr(_ip);
    result = net::IP(*addr);
  }

  return result;
}
static void
update_hw_address (NMDevice *dev)
{
	NMDeviceWired *self = NM_DEVICE_WIRED (dev);
	NMDeviceWiredPrivate *priv = NM_DEVICE_WIRED_GET_PRIVATE (self);
	struct rtnl_link *rtnl;
	struct nl_addr *addr;

	rtnl = nm_netlink_index_to_rtnl_link (nm_device_get_ip_ifindex (dev));
	if (!rtnl) {
		nm_log_err (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (dev),
		            "(%s) failed to read hardware address (error %d)",
		            nm_device_get_iface (dev), errno);
		return;
	}

	addr = rtnl_link_get_addr (rtnl);
	if (!addr) {
		nm_log_err (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (dev),
		            "(%s) no hardware address?",
		            nm_device_get_iface (dev));
		rtnl_link_put (rtnl);
		return;
	}

	if (nl_addr_get_len (addr) != priv->hw_addr_len) {
		nm_log_err (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (dev),
		            "(%s) hardware address is wrong length (expected %d got %d)",
		            nm_device_get_iface (dev),
		            priv->hw_addr_len, nl_addr_get_len (addr));
	} else {
		memcpy (&priv->hw_addr, nl_addr_get_binary_addr (addr),
				priv->hw_addr_len);
	}

	rtnl_link_put (rtnl);
}
Esempio n. 6
0
File: inet6.c Progetto: Domikk/libnl
/**
 * Set IPv6 tokenized interface identifier
 * @arg link		Link object
 * @arg token		Tokenized interface identifier
 *
 * Sets the link's IPv6 tokenized interface identifier.
 *
 * @return 0 on success
 * @return -NLE_NOMEM could not allocate inet6 data
 * @return -NLE_INVAL addr is not a valid inet6 address
 */
int rtnl_link_inet6_set_token(struct rtnl_link *link, struct nl_addr *addr)
{
	struct inet6_data *id;

	if ((nl_addr_get_family(addr) != AF_INET6) ||
	    (nl_addr_get_len(addr) != sizeof(id->i6_token)))
		return -NLE_INVAL;

	if (!(id = rtnl_link_af_alloc(link, &inet6_ops)))
		return -NLE_NOMEM;

	memcpy(&id->i6_token, nl_addr_get_binary_addr(addr),
	       sizeof(id->i6_token));
	return 0;
}
static int
get_hwaddr (int ifindex, guint8 *buf)
{
	struct rtnl_link *lk;
	struct nl_addr *addr;
	int len;

	lk = nm_netlink_index_to_rtnl_link (ifindex);
	if (!lk)
		return -1;

	addr = rtnl_link_get_addr (lk);
	len = nl_addr_get_len (addr);
	if (len > NM_UTILS_HWADDR_LEN_MAX)
		len = -1;
	else
		memcpy (buf, nl_addr_get_binary_addr (addr), len);

	rtnl_link_put (lk);
	return len;
}
Esempio n. 8
0
File: ae.c Progetto: Domikk/libnl
int xfrmnl_ae_build_get_request(struct nl_addr* daddr, unsigned int spi, unsigned int protocol,
                                unsigned int mark_mask, unsigned int mark_value, struct nl_msg **result)
{
	struct nl_msg *msg;
	struct xfrm_aevent_id   ae_id;
	struct xfrmnl_mark   mark;

	if (!daddr || !spi)
	{
		fprintf(stderr, "APPLICATION BUG: %s:%d:%s: A valid destination address, spi must be specified\n",
				__FILE__, __LINE__, __PRETTY_FUNCTION__);
		assert(0);
		return -NLE_MISSING_ATTR;
	}

	memset(&ae_id, 0, sizeof(ae_id));
	memcpy (&ae_id.sa_id.daddr, nl_addr_get_binary_addr (daddr), sizeof (uint8_t) * nl_addr_get_len (daddr));
	ae_id.sa_id.spi    = htonl(spi);
	ae_id.sa_id.family = nl_addr_get_family (daddr);
	ae_id.sa_id.proto  = protocol;

	if (!(msg = nlmsg_alloc_simple(XFRM_MSG_GETAE, 0)))
		return -NLE_NOMEM;

	if (nlmsg_append(msg, &ae_id, sizeof(ae_id), NLMSG_ALIGNTO) < 0)
		goto nla_put_failure;

	mark.m  =   mark_mask;
	mark.v  =   mark_value;
	NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrmnl_mark), &mark);

	*result = msg;
	return 0;

nla_put_failure:
	nlmsg_free(msg);
	return -NLE_MSGSIZE;
}
Esempio n. 9
0
void nl_bridge::remove_neigh_from_fdb(rtnl_neigh *neigh) {
  assert(sw);
  nl_addr *addr = rtnl_neigh_get_lladdr(neigh);

  if (nl_addr_cmp(rtnl_link_get_addr(bridge), addr) == 0) {
    // ignore ll addr of bridge on slave
    return;
  }

  // lookup l2_cache as well
  std::unique_ptr<rtnl_neigh, decltype(&rtnl_neigh_put)> n_lookup(
      NEIGH_CAST(nl_cache_search(l2_cache.get(), OBJ_CAST(neigh))),
      rtnl_neigh_put);

  if (n_lookup) {
    nl_cache_remove(OBJ_CAST(n_lookup.get()));
  }

  const uint32_t port = nl->get_port_id(rtnl_neigh_get_ifindex(neigh));
  rofl::caddress_ll mac((uint8_t *)nl_addr_get_binary_addr(addr),
                        nl_addr_get_len(addr));

  sw->l2_addr_remove(port, rtnl_neigh_get_vlan(neigh), mac);
}
Esempio n. 10
0
bool TNlAddr::IsHost() const {
    return Addr && nl_addr_get_prefixlen(Addr) == nl_addr_get_len(Addr) * 8;
}
Esempio n. 11
0
TError TNlLink::AddXVlan(const std::string &vlantype,
                         const std::string &master,
                         uint32_t type,
                         const std::string &hw,
                         int mtu) {
    TError error = TError::Success();
    int ret;
    uint32_t masterIdx;
    struct nl_msg *msg;
    struct nlattr *linkinfo, *infodata;
    struct ifinfomsg ifi = { 0 };
    struct ether_addr *ea = nullptr;
    auto Name = GetName();

    if (hw.length()) {
        // FIXME THREADS
        ea = ether_aton(hw.c_str());
        if (!ea)
            return TError(EError::Unknown, "Invalid " + vlantype + " mac address " + hw);
    }

    TNlLink masterLink(Nl, master);
    error = masterLink.Load();
    if (error)
        return error;
    masterIdx = masterLink.GetIndex();

    msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_CREATE);
    if (!msg)
        return TError(EError::Unknown, "Unable to add " + vlantype + ": no memory");

    ret = nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO);
    if (ret < 0) {
        error = TError(EError::Unknown, "Unable to add " + vlantype + ": " + nl_geterror(ret));
        goto free_msg;
    }

    /* link configuration */
    ret = nla_put(msg, IFLA_LINK, sizeof(uint32_t), &masterIdx);
    if (ret < 0) {
        error = TError(EError::Unknown, std::string("Unable to put IFLA_LINK: ") + nl_geterror(ret));
        goto free_msg;
    }
    ret = nla_put(msg, IFLA_IFNAME, Name.length() + 1, Name.c_str());
    if (ret < 0) {
        error = TError(EError::Unknown, std::string("Unable to put IFLA_IFNAME: ") + nl_geterror(ret));
        goto free_msg;
    }

    if (mtu > 0) {
        ret = nla_put(msg, IFLA_MTU, sizeof(int), &mtu);
        if (ret < 0) {
            error = TError(EError::Unknown, std::string("Unable to put IFLA_MTU: ") + nl_geterror(ret));
            goto free_msg;
        }
    }

    if (ea) {
        struct nl_addr *addr = nl_addr_build(AF_LLC, ea, ETH_ALEN);
        ret = nla_put(msg, IFLA_ADDRESS, nl_addr_get_len(addr), nl_addr_get_binary_addr(addr));
        if (ret < 0) {
            error = TError(EError::Unknown, std::string("Unable to put IFLA_ADDRESS: ") + nl_geterror(ret));
            goto free_msg;
        }
        nl_addr_put(addr);
    }

    /* link type */
    linkinfo = nla_nest_start(msg, IFLA_LINKINFO);
    if (!linkinfo) {
        error = TError(EError::Unknown, "Unable to add " + vlantype + ": can't nest IFLA_LINKINFO");
        goto free_msg;
    }
    ret = nla_put(msg, IFLA_INFO_KIND, vlantype.length() + 1, vlantype.c_str());
    if (ret < 0) {
        error = TError(EError::Unknown, std::string("Unable to put IFLA_INFO_KIND: ") + nl_geterror(ret));
        goto free_msg;
    }

    /* xvlan specific */
    infodata = nla_nest_start(msg, IFLA_INFO_DATA);
    if (!infodata) {
        error = TError(EError::Unknown, "Unable to add " + vlantype + ": can't nest IFLA_INFO_DATA");
        goto free_msg;
    }

    if (vlantype == "macvlan") {
        ret = nla_put(msg, IFLA_MACVLAN_MODE, sizeof(uint32_t), &type);
        if (ret < 0) {
            error = TError(EError::Unknown, std::string("Unable to put IFLA_MACVLAN_MODE: ") + nl_geterror(ret));
            goto free_msg;
        }
#ifdef IFLA_IPVLAN_MAX
    } else if (vlantype == "ipvlan") {
        uint16_t mode = type;
        ret = nla_put(msg, IFLA_IPVLAN_MODE, sizeof(uint16_t), &mode);
        if (ret < 0) {
            error = TError(EError::Unknown, std::string("Unable to put IFLA_IPVLAN_MODE: ") + nl_geterror(ret));
            goto free_msg;
        }
#endif
    }
    nla_nest_end(msg, infodata);
    nla_nest_end(msg, linkinfo);

    L() << "netlink: add " << vlantype << " " << Name << " master " << master
        << " type " << type << " hw " << hw << " mtu " << mtu << std::endl;

    ret = nl_send_sync(GetSock(), msg);
    if (ret)
        return Error(ret, "Cannot add " + vlantype);

    return Load();

free_msg:
    nlmsg_free(msg);
    return error;

}
Esempio n. 12
0
File: ae.c Progetto: Domikk/libnl
static int build_xfrm_ae_message(struct xfrmnl_ae *tmpl, int cmd, int flags,
			   struct nl_msg **result)
{
	struct nl_msg*          msg;
	struct xfrm_aevent_id   ae_id;

	if (!(tmpl->ce_mask & XFRM_AE_ATTR_DADDR) ||
		!(tmpl->ce_mask & XFRM_AE_ATTR_SPI) ||
		!(tmpl->ce_mask & XFRM_AE_ATTR_PROTO))
		return -NLE_MISSING_ATTR;

	memcpy (&ae_id.sa_id.daddr, nl_addr_get_binary_addr (tmpl->sa_id.daddr), sizeof (uint8_t) * nl_addr_get_len (tmpl->sa_id.daddr));
	ae_id.sa_id.spi    = htonl(tmpl->sa_id.spi);
	ae_id.sa_id.family = tmpl->sa_id.family;
	ae_id.sa_id.proto  = tmpl->sa_id.proto;

	if (tmpl->ce_mask & XFRM_AE_ATTR_SADDR)
		memcpy (&ae_id.saddr, nl_addr_get_binary_addr (tmpl->saddr), sizeof (uint8_t) * nl_addr_get_len (tmpl->saddr));

	if (tmpl->ce_mask & XFRM_AE_ATTR_FLAGS)
		ae_id.flags    = tmpl->flags;

	if (tmpl->ce_mask & XFRM_AE_ATTR_REQID)
		ae_id.reqid    = tmpl->reqid;

	msg = nlmsg_alloc_simple(cmd, flags);
	if (!msg)
		return -NLE_NOMEM;

	if (nlmsg_append(msg, &ae_id, sizeof(ae_id), NLMSG_ALIGNTO) < 0)
		goto nla_put_failure;

	if (tmpl->ce_mask & XFRM_AE_ATTR_MARK)
		NLA_PUT (msg, XFRMA_MARK, sizeof (struct xfrmnl_mark), &tmpl->mark);

	if (tmpl->ce_mask & XFRM_AE_ATTR_LIFETIME)
		NLA_PUT (msg, XFRMA_LTIME_VAL, sizeof (struct xfrmnl_lifetime_cur), &tmpl->lifetime_cur);

	if (tmpl->ce_mask & XFRM_AE_ATTR_REPLAY_MAXAGE)
		NLA_PUT_U32 (msg, XFRMA_ETIMER_THRESH, tmpl->replay_maxage);

	if (tmpl->ce_mask & XFRM_AE_ATTR_REPLAY_MAXDIFF)
		NLA_PUT_U32 (msg, XFRMA_REPLAY_THRESH, tmpl->replay_maxdiff);

	if (tmpl->ce_mask & XFRM_AE_ATTR_REPLAY_STATE) {
		if (tmpl->replay_state_esn) {
			uint32_t len = sizeof (struct xfrm_replay_state_esn) + (sizeof (uint32_t) * tmpl->replay_state_esn->bmp_len);
			NLA_PUT (msg, XFRMA_REPLAY_ESN_VAL, len, tmpl->replay_state_esn);
		}
		else {
			NLA_PUT (msg, XFRMA_REPLAY_VAL, sizeof (struct xfrmnl_replay_state), &tmpl->replay_state);
		}
	}

	*result = msg;
	return 0;

nla_put_failure:
	nlmsg_free(msg);
	return -NLE_MSGSIZE;
}