net/ipv6: Switch NA msg sending to new net_pkt API
And let's use net_ipv6_create, net_icmpv6_create, net_ipv6_finalize to factorize the code better. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
fc38d0929d
commit
82f027460a
|
@ -915,6 +915,25 @@ static inline u8_t get_llao_len(struct net_if *iface)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline bool set_llao_new(struct net_pkt *pkt,
|
||||
struct net_linkaddr *lladdr,
|
||||
u8_t llao_len, u8_t type)
|
||||
{
|
||||
struct net_icmpv6_nd_opt_hdr opt_hdr = {
|
||||
.type = type,
|
||||
.len = llao_len >> 3,
|
||||
};
|
||||
|
||||
if (net_pkt_write_new(pkt, &opt_hdr,
|
||||
sizeof(struct net_icmpv6_nd_opt_hdr)) ||
|
||||
net_pkt_write_new(pkt, lladdr->addr, lladdr->len) ||
|
||||
net_pkt_memset(pkt, 0, llao_len - lladdr->len - 2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void set_llao(struct net_linkaddr *lladdr,
|
||||
u8_t *llao, u8_t llao_len, u8_t type)
|
||||
{
|
||||
|
@ -985,81 +1004,72 @@ int net_ipv6_send_na(struct net_if *iface, const struct in6_addr *src,
|
|||
const struct in6_addr *dst, const struct in6_addr *tgt,
|
||||
u8_t flags)
|
||||
{
|
||||
struct net_icmpv6_na_hdr na_hdr;
|
||||
NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(na_access,
|
||||
struct net_icmpv6_na_hdr);
|
||||
int ret = -ENOBUFS;
|
||||
struct net_icmpv6_na_hdr *na_hdr;
|
||||
struct net_pkt *pkt;
|
||||
struct net_buf *frag;
|
||||
u8_t llao_len;
|
||||
int ret;
|
||||
|
||||
pkt = net_pkt_get_reserve_tx(ND_NET_BUF_TIMEOUT);
|
||||
llao_len = get_llao_len(iface);
|
||||
|
||||
pkt = net_pkt_alloc_with_buffer(iface,
|
||||
sizeof(struct net_icmpv6_na_hdr) +
|
||||
llao_len,
|
||||
AF_INET6, IPPROTO_ICMPV6,
|
||||
ND_NET_BUF_TIMEOUT);
|
||||
if (!pkt) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_pkt_get_frag(pkt, ND_NET_BUF_TIMEOUT);
|
||||
if (!frag) {
|
||||
net_pkt_unref(pkt);
|
||||
return -ENOMEM;
|
||||
}
|
||||
net_pkt_set_ipv6_hop_limit(pkt, NET_IPV6_ND_HOP_LIMIT);
|
||||
|
||||
net_pkt_frag_add(pkt, frag);
|
||||
|
||||
net_pkt_set_iface(pkt, iface);
|
||||
net_pkt_set_family(pkt, AF_INET6);
|
||||
net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv6_hdr));
|
||||
|
||||
llao_len = get_llao_len(iface);
|
||||
|
||||
net_pkt_set_ipv6_ext_len(pkt, 0);
|
||||
|
||||
setup_headers(pkt, sizeof(struct net_icmpv6_na_hdr) + llao_len,
|
||||
NET_ICMPV6_NA);
|
||||
|
||||
net_buf_add(frag, sizeof(struct net_icmpv6_na_hdr) + llao_len);
|
||||
|
||||
net_ipaddr_copy(&NET_IPV6_HDR(pkt)->src, src);
|
||||
net_ipaddr_copy(&NET_IPV6_HDR(pkt)->dst, dst);
|
||||
net_ipaddr_copy(&na_hdr.tgt, tgt);
|
||||
|
||||
set_llao(net_if_get_link_addr(net_pkt_iface(pkt)),
|
||||
(u8_t *)net_pkt_icmp_data(pkt) + sizeof(struct net_icmp_hdr) +
|
||||
sizeof(struct net_icmpv6_na_hdr),
|
||||
llao_len, NET_ICMPV6_ND_OPT_TLLAO);
|
||||
|
||||
na_hdr.flags = flags;
|
||||
ret = net_icmpv6_set_na_hdr(pkt, &na_hdr);
|
||||
if (ret < 0) {
|
||||
net_pkt_unref(pkt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pkt->frags->len = NET_IPV6ICMPH_LEN +
|
||||
sizeof(struct net_icmpv6_na_hdr) + llao_len;
|
||||
|
||||
ret = net_icmpv6_set_chksum(pkt);
|
||||
if (ret < 0) {
|
||||
net_pkt_unref(pkt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dbg_addr_sent_tgt("Neighbor Advertisement",
|
||||
&NET_IPV6_HDR(pkt)->src,
|
||||
&NET_IPV6_HDR(pkt)->dst,
|
||||
&na_hdr.tgt);
|
||||
|
||||
if (net_send_data(pkt) < 0) {
|
||||
if (net_ipv6_create_new(pkt, src, dst) ||
|
||||
net_icmpv6_create(pkt, NET_ICMPV6_NA, 0)) {
|
||||
goto drop;
|
||||
}
|
||||
|
||||
net_stats_update_ipv6_nd_sent(net_pkt_iface(pkt));
|
||||
na_hdr = (struct net_icmpv6_na_hdr *)net_pkt_get_data_new(pkt,
|
||||
&na_access);
|
||||
if (!na_hdr) {
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* Let's make sure reserved part is full of 0 */
|
||||
memset(na_hdr, 0, sizeof(struct net_icmpv6_na_hdr));
|
||||
|
||||
na_hdr->flags = flags;
|
||||
net_ipaddr_copy(&na_hdr->tgt, tgt);
|
||||
|
||||
if (net_pkt_set_data(pkt, &na_access)) {
|
||||
goto drop;
|
||||
}
|
||||
|
||||
if (!set_llao_new(pkt, net_if_get_link_addr(iface),
|
||||
llao_len, NET_ICMPV6_ND_OPT_TLLAO)) {
|
||||
goto drop;
|
||||
}
|
||||
|
||||
net_pkt_cursor_init(pkt);
|
||||
net_ipv6_finalize_new(pkt, IPPROTO_ICMPV6);
|
||||
|
||||
dbg_addr_sent_tgt("Neighbor Advertisement", src, dst, &na_hdr->tgt);
|
||||
|
||||
if (net_send_data(pkt) < 0) {
|
||||
net_stats_update_ipv6_nd_drop(iface);
|
||||
ret = -EINVAL;
|
||||
|
||||
goto drop;
|
||||
}
|
||||
|
||||
net_stats_update_ipv6_nd_sent(iface);
|
||||
|
||||
return 0;
|
||||
|
||||
drop:
|
||||
net_stats_update_ipv6_nd_drop(net_pkt_iface(pkt));
|
||||
net_pkt_unref(pkt);
|
||||
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ns_routing_info(struct net_pkt *pkt,
|
||||
|
|
Loading…
Reference in a new issue