-/* $OpenBSD: if.c,v 1.694 2023/04/26 19:54:35 mvs Exp $ */
+/* $OpenBSD: if.c,v 1.695 2023/05/07 16:23:23 bluhm Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
return (0);
}
-void
-if_mqoutput(struct ifnet *ifp, struct mbuf_queue *mq, unsigned int *total,
- struct sockaddr *dst, struct rtentry *rt)
-{
- struct mbuf_list ml;
- struct mbuf *m;
- unsigned int len;
-
- mq_delist(mq, &ml);
- len = ml_len(&ml);
- while ((m = ml_dequeue(&ml)) != NULL)
- ifp->if_output(ifp, m, rt_key(rt), rt);
-
- /* XXXSMP we also discard if other CPU enqueues */
- if (mq_len(mq) > 0) {
- /* mbuf is back in queue. Discard. */
- atomic_sub_int(total, len + mq_purge(mq));
- } else
- atomic_sub_int(total, len);
-}
-
void
if_input(struct ifnet *ifp, struct mbuf_list *ml)
{
return (0);
}
+int
+if_output_ml(struct ifnet *ifp, struct mbuf_list *ml,
+ struct sockaddr *dst, struct rtentry *rt)
+{
+ struct mbuf *m;
+ int error = 0;
+
+ while ((m = ml_dequeue(ml)) != NULL) {
+ error = ifp->if_output(ifp, m, dst, rt);
+ if (error)
+ break;
+ }
+ if (error)
+ ml_purge(ml);
+
+ return error;
+}
+
+int
+if_output_mq(struct ifnet *ifp, struct mbuf_queue *mq, unsigned int *total,
+ struct sockaddr *dst, struct rtentry *rt)
+{
+ struct mbuf_list ml;
+ unsigned int len;
+ int error;
+
+ mq_delist(mq, &ml);
+ len = ml_len(&ml);
+ error = if_output_ml(ifp, &ml, dst, rt);
+
+ /* XXXSMP we also discard if other CPU enqueues */
+ if (mq_len(mq) > 0) {
+ /* mbuf is back in queue. Discard. */
+ atomic_sub_int(total, len + mq_purge(mq));
+ } else
+ atomic_sub_int(total, len);
+
+ return error;
+}
+
int
if_output_local(struct ifnet *ifp, struct mbuf *m, sa_family_t af)
{
-/* $OpenBSD: if_bridge.c,v 1.365 2023/02/27 09:35:32 jan Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.366 2023/05/07 16:23:23 bluhm Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
struct mbuf *m)
{
struct llc llc;
- struct mbuf_list fml;
+ struct mbuf_list ml;
int error = 0;
int hassnap = 0;
u_int16_t etype;
return;
}
- error = ip_fragment(m, &fml, ifp, ifp->if_mtu);
+ error = ip_fragment(m, &ml, ifp, ifp->if_mtu);
if (error)
return;
- while ((m = ml_dequeue(&fml)) != NULL) {
+ while ((m = ml_dequeue(&ml)) != NULL) {
if (hassnap) {
M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT);
if (m == NULL) {
break;
}
if (error)
- ml_purge(&fml);
+ ml_purge(&ml);
else
ipstat_inc(ips_fragmented);
-/* $OpenBSD: if_var.h,v 1.125 2023/04/18 22:01:24 mvs Exp $ */
+/* $OpenBSD: if_var.h,v 1.126 2023/05/07 16:23:23 bluhm Exp $ */
/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
/*
void if_start(struct ifnet *);
int if_enqueue(struct ifnet *, struct mbuf *);
int if_enqueue_ifq(struct ifnet *, struct mbuf *);
-void if_mqoutput(struct ifnet *, struct mbuf_queue *, unsigned int *,
- struct sockaddr *, struct rtentry *);
void if_input(struct ifnet *, struct mbuf_list *);
void if_vinput(struct ifnet *, struct mbuf *);
void if_input_process(struct ifnet *, struct mbuf_list *);
int if_input_local(struct ifnet *, struct mbuf *, sa_family_t);
+int if_output_ml(struct ifnet *, struct mbuf_list *,
+ struct sockaddr *, struct rtentry *);
+int if_output_mq(struct ifnet *, struct mbuf_queue *, unsigned int *,
+ struct sockaddr *, struct rtentry *);
int if_output_local(struct ifnet *, struct mbuf *, sa_family_t);
void if_rtrequest_dummy(struct ifnet *, int, struct rtentry *);
void p2p_rtrequest(struct ifnet *, int, struct rtentry *);
-/* $OpenBSD: pf.c,v 1.1175 2023/05/03 10:32:47 kn Exp $ */
+/* $OpenBSD: pf.c,v 1.1176 2023/05/07 16:23:23 bluhm Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
pf_route(struct pf_pdesc *pd, struct pf_state *st)
{
struct mbuf *m0;
- struct mbuf_list fml;
+ struct mbuf_list ml;
struct sockaddr_in *dst, sin;
struct rtentry *rt = NULL;
struct ip *ip;
struct ifnet *ifp = NULL;
- int error = 0;
unsigned int rtableid;
if (pd->m->m_pkthdr.pf.routed++ > 3) {
ipstat_inc(ips_outswcsum);
ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
}
- error = ifp->if_output(ifp, m0, sintosa(dst), rt);
+ ifp->if_output(ifp, m0, sintosa(dst), rt);
goto done;
}
goto bad;
}
- error = ip_fragment(m0, &fml, ifp, ifp->if_mtu);
- if (error)
+ if (ip_fragment(m0, &ml, ifp, ifp->if_mtu) ||
+ if_output_ml(ifp, &ml, sintosa(dst), rt))
goto done;
-
- while ((m0 = ml_dequeue(&fml)) != NULL) {
- error = ifp->if_output(ifp, m0, sintosa(dst), rt);
- if (error)
- break;
- }
- if (error)
- ml_purge(&fml);
- else
- ipstat_inc(ips_fragmented);
+ ipstat_inc(ips_fragmented);
done:
if_put(ifp);
*/
if ((mtag = m_tag_find(m0, PACKET_TAG_PF_REASSEMBLED, NULL))) {
(void) pf_refragment6(&m0, mtag, dst, ifp, rt);
- } else if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
+ goto done;
+ }
+
+ if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
ifp->if_output(ifp, m0, sin6tosa(dst), rt);
- } else {
- ip6stat_inc(ip6s_cantfrag);
- if (st->rt != PF_DUPTO)
- pf_send_icmp(m0, ICMP6_PACKET_TOO_BIG, 0,
- ifp->if_mtu, pd->af, st->rule.ptr, pd->rdomain);
- goto bad;
+ goto done;
}
+ ip6stat_inc(ip6s_cantfrag);
+ if (st->rt != PF_DUPTO)
+ pf_send_icmp(m0, ICMP6_PACKET_TOO_BIG, 0,
+ ifp->if_mtu, pd->af, st->rule.ptr, pd->rdomain);
+ goto bad;
+
done:
if_put(ifp);
rtfree(rt);
-/* $OpenBSD: pf_norm.c,v 1.226 2022/11/06 18:05:05 dlg Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.227 2023/05/07 16:23:23 bluhm Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
struct ifnet *ifp, struct rtentry *rt)
{
struct mbuf *m = *m0;
- struct mbuf_list fml;
+ struct mbuf_list ml;
struct pf_fragment_tag *ftag = (struct pf_fragment_tag *)(mtag + 1);
u_int32_t mtu;
u_int16_t hdrlen, extoff, maxlen;
* we drop the packet.
*/
mtu = hdrlen + sizeof(struct ip6_frag) + maxlen;
- error = ip6_fragment(m, &fml, hdrlen, proto, mtu);
+ error = ip6_fragment(m, &ml, hdrlen, proto, mtu);
*m0 = NULL; /* ip6_fragment() has consumed original packet. */
if (error) {
DPFPRINTF(LOG_NOTICE, "refragment error %d", error);
return (PF_DROP);
}
- while ((m = ml_dequeue(&fml)) != NULL) {
+ while ((m = ml_dequeue(&ml)) != NULL) {
m->m_pkthdr.pf.flags |= PF_TAG_REFRAGMENTED;
if (ifp == NULL) {
ip6_forward(m, NULL, 0);
-/* $OpenBSD: if_ether.c,v 1.263 2023/04/25 16:24:25 bluhm Exp $ */
+/* $OpenBSD: if_ether.c,v 1.264 2023/05/07 16:23:23 bluhm Exp $ */
/* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */
/*
la->la_asked = 0;
la->la_refreshed = 0;
- if_mqoutput(ifp, &la->la_mq, &la_hold_total, rt_key(rt), rt);
+ if_output_mq(ifp, &la->la_mq, &la_hold_total, rt_key(rt), rt);
return (0);
}
-/* $OpenBSD: ip_output.c,v 1.382 2022/08/12 17:04:16 bluhm Exp $ */
+/* $OpenBSD: ip_output.c,v 1.383 2023/05/07 16:23:23 bluhm Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
{
struct ip *ip;
struct ifnet *ifp = NULL;
- struct mbuf_list fml;
+ struct mbuf_list ml;
int hlen = sizeof (struct ip);
int error = 0;
struct route iproute;
goto bad;
}
- error = ip_fragment(m, &fml, ifp, mtu);
- if (error)
+ if ((error = ip_fragment(m, &ml, ifp, mtu)) ||
+ (error = if_output_ml(ifp, &ml, sintosa(dst), ro->ro_rt)))
goto done;
-
- while ((m = ml_dequeue(&fml)) != NULL) {
- error = ifp->if_output(ifp, m, sintosa(dst), ro->ro_rt);
- if (error)
- break;
- }
- if (error)
- ml_purge(&fml);
- else
- ipstat_inc(ips_fragmented);
+ ipstat_inc(ips_fragmented);
done:
if (ro == &iproute && ro->ro_rt)
#endif /* IPSEC */
int
-ip_fragment(struct mbuf *m0, struct mbuf_list *fml, struct ifnet *ifp,
+ip_fragment(struct mbuf *m0, struct mbuf_list *ml, struct ifnet *ifp,
u_long mtu)
{
- struct mbuf *m;
struct ip *ip;
int firstlen, hlen, tlen, len, off;
int error;
- ml_init(fml);
- ml_enqueue(fml, m0);
+ ml_init(ml);
+ ml_enqueue(ml, m0);
ip = mtod(m0, struct ip *);
hlen = ip->ip_hl << 2;
in_proto_cksum_out(m0, NULL);
/*
- * Loop through length of segment after first fragment,
+ * Loop through length of payload after first fragment,
* make new header and copy data of each part and link onto chain.
*/
for (off = hlen + firstlen; off < tlen; off += len) {
+ struct mbuf *m;
struct ip *mhip;
int mhlen;
error = ENOBUFS;
goto bad;
}
- ml_enqueue(fml, m);
-
+ ml_enqueue(ml, m);
if ((error = m_dup_pkthdr(m, m0, M_DONTWAIT)) != 0)
goto bad;
m->m_data += max_linkhdr;
* Update first fragment by trimming what's been copied out
* and updating header, then send each fragment (in order).
*/
- m = m0;
- m_adj(m, hlen + firstlen - tlen);
- ip->ip_off |= htons(IP_MF);
- ip->ip_len = htons(m->m_pkthdr.len);
+ if (hlen + firstlen < tlen) {
+ m_adj(m0, hlen + firstlen - tlen);
+ ip->ip_off |= htons(IP_MF);
+ }
+ ip->ip_len = htons(m0->m_pkthdr.len);
ip->ip_sum = 0;
- if (in_ifcap_cksum(m, ifp, IFCAP_CSUM_IPv4))
- m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
+ if (in_ifcap_cksum(m0, ifp, IFCAP_CSUM_IPv4))
+ m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
else {
ipstat_inc(ips_outswcsum);
- ip->ip_sum = in_cksum(m, hlen);
+ ip->ip_sum = in_cksum(m0, hlen);
}
- ipstat_add(ips_ofragments, ml_len(fml));
+ ipstat_add(ips_ofragments, ml_len(ml));
return (0);
bad:
ipstat_inc(ips_odropped);
- ml_purge(fml);
+ ml_purge(ml);
return (error);
}
-/* $OpenBSD: ip6_output.c,v 1.272 2022/11/12 02:50:59 kn Exp $ */
+/* $OpenBSD: ip6_output.c,v 1.273 2023/05/07 16:23:24 bluhm Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
{
struct ip6_hdr *ip6;
struct ifnet *ifp = NULL;
- struct mbuf_list fml;
+ struct mbuf_list ml;
int hlen, tlen;
struct route_in6 ip6route;
struct rtentry *rt = NULL;
ip6->ip6_nxt = IPPROTO_FRAGMENT;
}
- error = ip6_fragment(m, &fml, hlen, nextproto, mtu);
- if (error)
+ if ((error = ip6_fragment(m, &ml, hlen, nextproto, mtu)) ||
+ (error = if_output_ml(ifp, &ml, sin6tosa(dst), ro->ro_rt)))
goto done;
-
- while ((m = ml_dequeue(&fml)) != NULL) {
- error = ifp->if_output(ifp, m, sin6tosa(dst), ro->ro_rt);
- if (error)
- break;
- }
- if (error)
- ml_purge(&fml);
- else
- ip6stat_inc(ip6s_fragmented);
+ ip6stat_inc(ip6s_fragmented);
done:
if (ro == &ip6route && ro->ro_rt) {
}
int
-ip6_fragment(struct mbuf *m0, struct mbuf_list *fml, int hlen,
- u_char nextproto, u_long mtu)
+ip6_fragment(struct mbuf *m0, struct mbuf_list *ml, int hlen, u_char nextproto,
+ u_long mtu)
{
- struct mbuf *m;
struct ip6_hdr *ip6;
u_int32_t id;
int tlen, len, off;
int error;
- ml_init(fml);
+ ml_init(ml);
ip6 = mtod(m0, struct ip6_hdr *);
tlen = m0->m_pkthdr.len;
id = htonl(ip6_randomid());
/*
- * Loop through length of segment,
+ * Loop through length of payload,
* make new header and copy data of each part and link onto chain.
*/
for (off = hlen; off < tlen; off += len) {
+ struct mbuf *m;
struct mbuf *mlast;
struct ip6_hdr *mhip6;
struct ip6_frag *ip6f;
error = ENOBUFS;
goto bad;
}
- ml_enqueue(fml, m);
-
+ ml_enqueue(ml, m);
if ((error = m_dup_pkthdr(m, m0, M_DONTWAIT)) != 0)
goto bad;
m->m_data += max_linkhdr;
ip6f->ip6f_nxt = nextproto;
}
- ip6stat_add(ip6s_ofragments, ml_len(fml));
+ ip6stat_add(ip6s_ofragments, ml_len(ml));
m_freem(m0);
return (0);
bad:
ip6stat_inc(ip6s_odropped);
- ml_purge(fml);
+ ml_purge(ml);
m_freem(m0);
return (error);
}
-/* $OpenBSD: nd6.c,v 1.275 2023/05/04 06:56:56 bluhm Exp $ */
+/* $OpenBSD: nd6.c,v 1.276 2023/05/07 16:23:24 bluhm Exp $ */
/* $KAME: nd6.c,v 1.280 2002/06/08 19:52:07 itojun Exp $ */
/*
* meaningless.
*/
nd6_llinfo_settimer(ln, nd6_gctimer);
- if_mqoutput(ifp, &ln->ln_mq, &ln_hold_total,
+ if_output_mq(ifp, &ln->ln_mq, &ln_hold_total,
rt_key(rt), rt);
} else if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
/* probe right away */
-/* $OpenBSD: nd6_nbr.c,v 1.148 2023/05/04 06:56:56 bluhm Exp $ */
+/* $OpenBSD: nd6_nbr.c,v 1.149 2023/05/07 16:23:24 bluhm Exp $ */
/* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */
/*
}
rt->rt_flags &= ~RTF_REJECT;
ln->ln_asked = 0;
- if_mqoutput(ifp, &ln->ln_mq, &ln_hold_total, rt_key(rt), rt);
+ if_output_mq(ifp, &ln->ln_mq, &ln_hold_total, rt_key(rt), rt);
freeit:
rtfree(rt);