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:
Tomasz Bursztyka 2018-12-20 10:33:35 +01:00 committed by Jukka Rissanen
parent fc38d0929d
commit 82f027460a

View file

@ -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,