diff options
author | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2000-01-13 00:35:00 +0000 |
---|---|---|
committer | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2000-01-13 00:35:00 +0000 |
commit | b91ecf450f26655916500eefde03040a94a093fe (patch) | |
tree | 39b6090e4dbaab1c111280fdb4141e139bbcb6d5 /sys/net | |
parent | 2d9ee360cc46ad28442174db81cf9a7964d0c668 (diff) |
Ingress flow support.
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/pfkeyv2.c | 77 | ||||
-rw-r--r-- | sys/net/pfkeyv2.h | 1 |
2 files changed, 57 insertions, 21 deletions
diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c index 08aca100434..d2e8b7e0069 100644 --- a/sys/net/pfkeyv2.c +++ b/sys/net/pfkeyv2.c @@ -1352,7 +1352,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len) struct sockaddr_encap encapdst, encapgw, encapnetmask; struct flow *flow2 = NULL, *old_flow = NULL, *old_flow2 = NULL; union sockaddr_union *src, *dst, *srcmask, *dstmask; - u_int8_t sproto = 0, replace; + u_int8_t sproto = 0, replace, ingress ; struct rtentry *rt; ssa = (struct sadb_sa *) headers[SADB_EXT_SA]; @@ -1361,10 +1361,12 @@ pfkeyv2_send(struct socket *socket, void *message, int len) /* * SADB_X_SAFLAGS_REPLACEFLOW set means we should remove any - * potentially conflicting flow while we are adding this new one. + * potentially conflicting egress flow while we are adding this + * new one. */ replace = ssa->sadb_sa_flags & SADB_X_SAFLAGS_REPLACEFLOW; - if (replace && delflag) + ingress = ssa->sadb_sa_flags & SADB_X_SAFLAGS_INGRESS_FLOW; + if ((replace && delflag) || (replace && ingress)) { rval = EINVAL; goto ret; @@ -1406,7 +1408,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len) s = spltdb(); - if (!delflag) + if (!delflag || ingress) { /* Find the relevant SA */ sa2 = gettdb(ssa->sadb_sa_spi, sunionp, @@ -1419,15 +1421,25 @@ pfkeyv2_send(struct socket *socket, void *message, int len) } } - - flow = find_global_flow(src, srcmask, dst, dstmask, sproto); - if (!replace && - ((delflag && (flow == NULL)) || (!delflag && (flow != NULL)))) + /* For non-ingress flows... */ + if (!ingress) { - rval = delflag ? ESRCH : EEXIST; - goto splxret; + /* + * ...if the requested flow already exists and we aren't + * asked to replace or delete it, or if it doesn't exist + * and we're asked to delete it, fail. + */ + flow = find_global_flow(src, srcmask, dst, dstmask, sproto); + if (!replace && + ((delflag && (flow == NULL)) || + (!delflag && (flow != NULL)))) + { + rval = delflag ? ESRCH : EEXIST; + goto splxret; + } } + /* If we're not deleting a flow, add in the TDB */ if (!delflag) { if (replace) @@ -1439,8 +1451,31 @@ pfkeyv2_send(struct socket *socket, void *message, int len) bcopy(srcmask, &flow->flow_srcmask, srcmask->sa.sa_len); bcopy(dstmask, &flow->flow_dstmask, dstmask->sa.sa_len); flow->flow_proto = sproto; - put_flow(flow, sa2); + put_flow(flow, sa2, ingress); + + /* If this is an ACL entry, we're done */ + if (ingress) + { + splx(s); + break; + } } + else + if (ingress) + { + /* If we're deleting a flow... */ + flow = find_flow(src, dst, srcmask, dstmask, sproto, + sa2, FLOW_INGRESS); + if (flow == NULL) + { + rval = ESRCH; + goto splxret; + } + + delete_flow(flow, sa2, FLOW_INGRESS); + splx(s); + break; + } /* Setup the encap fields */ encapdst.sen_family = PF_KEY; @@ -1535,7 +1570,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len) * should be checked at establishment time. */ rval = EPFNOSUPPORT; - delete_flow(flow, flow->flow_sa); + delete_flow(flow, flow->flow_sa, FLOW_EGRESS); goto splxret; } } @@ -1548,7 +1583,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len) (struct sockaddr *) &encapnetmask, 0, (struct rtentry **) 0); - delete_flow(flow, flow->flow_sa); + delete_flow(flow, flow->flow_sa, FLOW_EGRESS); } else if (!replace) { @@ -1560,10 +1595,10 @@ pfkeyv2_send(struct socket *socket, void *message, int len) if (rval) { - delete_flow(flow, sa2); + delete_flow(flow, sa2, FLOW_EGRESS); if (flow2) - delete_flow(flow2, sa2); + delete_flow(flow2, sa2, FLOW_EGRESS); goto splxret; } @@ -1584,10 +1619,10 @@ pfkeyv2_send(struct socket *socket, void *message, int len) if (rval) { - delete_flow(flow, sa2); + delete_flow(flow, sa2, FLOW_EGRESS); if (flow2) - delete_flow(flow2, sa2); + delete_flow(flow2, sa2, FLOW_EGRESS); goto splxret; } @@ -1596,10 +1631,10 @@ pfkeyv2_send(struct socket *socket, void *message, int len) (struct sockaddr *) &encapgw)) { rval = ENOMEM; - delete_flow(flow, sa2); + delete_flow(flow, sa2, FLOW_EGRESS); if (flow2) - delete_flow(flow2, sa2); + delete_flow(flow2, sa2, FLOW_EGRESS); goto splxret; } @@ -1610,10 +1645,10 @@ pfkeyv2_send(struct socket *socket, void *message, int len) if (replace) { if (old_flow != NULL) - delete_flow(old_flow, old_flow->flow_sa); + delete_flow(old_flow, old_flow->flow_sa, FLOW_EGRESS); if (old_flow2 != NULL) - delete_flow(old_flow2, old_flow2->flow_sa); + delete_flow(old_flow2, old_flow2->flow_sa, FLOW_EGRESS); } /* If we are adding flows, check for allocation expirations */ diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h index 7c87d8eecf0..4c8f30fdd57 100644 --- a/sys/net/pfkeyv2.h +++ b/sys/net/pfkeyv2.h @@ -235,6 +235,7 @@ struct sadb_protocol { #define SADB_X_SAFLAGS_TUNNEL 0x04 /* Force tunneling */ #define SADB_X_SAFLAGS_CHAINDEL 0x08 /* Delete whole SA chain */ #define SADB_X_SAFLAGS_REPLACEFLOW 0x20 /* Replace existing flow */ +#define SADB_X_SAFLAGS_INGRESS_FLOW 0x40 /* Ingress ACL entry */ #define SADB_IDENTTYPE_RESERVED 0 #define SADB_IDENTTYPE_PREFIX 1 |