summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorNiels Provos <provos@cvs.openbsd.org>1997-07-15 23:11:11 +0000
committerNiels Provos <provos@cvs.openbsd.org>1997-07-15 23:11:11 +0000
commit9843662ad45ddecb7ea944318208f9203baa4df9 (patch)
tree56b05097ec5be4d837ede02b382b61c0ac375118 /sys/net
parentb56305855b048ed0bf6503aa0a7765cf3d5b04ee (diff)
flags for tunnels and replacing existing routes, sysctl! + tiny bug fix
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/encap.c118
-rw-r--r--sys/net/encap.h20
2 files changed, 129 insertions, 9 deletions
diff --git a/sys/net/encap.c b/sys/net/encap.c
index ea0d210c4d4..911ca641397 100644
--- a/sys/net/encap.c
+++ b/sys/net/encap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: encap.c,v 1.9 1997/07/14 08:46:39 provos Exp $ */
+/* $OpenBSD: encap.c,v 1.10 1997/07/15 23:11:08 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -164,12 +164,13 @@ va_dcl
{
#define SENDERR(e) do { error = e; goto flush;} while (0)
struct sockaddr_encap encapdst, encapgw, encapnetmask;
+ struct in_addr alts, altm;
int len, emlen, error = 0;
+ struct flow *flow, *flow2;
struct encap_msghdr *emp;
struct tdb *tdbp, *tdbp2;
caddr_t buffer = 0;
struct socket *so;
- struct flow *flow;
u_int32_t spi;
va_list ap;
@@ -454,10 +455,42 @@ va_dcl
if (flow != (struct flow *) NULL)
SENDERR(EEXIST);
+ /* Check for 0.0.0.0/255.255.255.255 if the flow is local */
+ if (emp->em_ena_flags & ENABLE_FLAG_LOCAL)
+ {
+ alts.s_addr = INADDR_ANY;
+ altm.s_addr = INADDR_BROADCAST;
+ flow2 = find_flow(alts, altm, emp->em_ena_idst,
+ emp->em_ena_idmask, emp->em_ena_protocol,
+ emp->em_ena_sport, emp->em_ena_dport, tdbp);
+ if (flow2 != (struct flow *) NULL)
+ SENDERR(EEXIST);
+ }
+
flow = get_flow();
if (flow == (struct flow *) NULL)
SENDERR(ENOBUFS);
+ if (emp->em_ena_flags & ENABLE_FLAG_LOCAL)
+ {
+ flow2 = get_flow();
+ if (flow2 == (struct flow *) NULL)
+ {
+ FREE(flow, M_TDB);
+ SENDERR(ENOBUFS);
+ }
+
+ flow2->flow_src.s_addr = INADDR_ANY;
+ flow2->flow_dst.s_addr = emp->em_ena_idst.s_addr;
+ flow2->flow_srcmask.s_addr = INADDR_BROADCAST;
+ flow2->flow_dstmask.s_addr = emp->em_ena_idmask.s_addr;
+ flow2->flow_proto = emp->em_ena_protocol;
+ flow2->flow_sport = emp->em_ena_sport;
+ flow2->flow_dport = emp->em_ena_dport;
+
+ put_flow(flow2, tdbp);
+ }
+
flow->flow_src.s_addr = emp->em_ena_isrc.s_addr;
flow->flow_dst.s_addr = emp->em_ena_idst.s_addr;
flow->flow_srcmask.s_addr = emp->em_ena_ismask.s_addr;
@@ -501,6 +534,14 @@ va_dcl
encapnetmask.sen_dport = 0xffff;
}
+ /* If this is set, delete any old route for this flow */
+ if (emp->em_ena_flags & ENABLE_FLAG_REPLACE)
+ rtrequest(RTM_DELETE, (struct sockaddr *) &encapdst,
+ (struct sockaddr *) &encapgw,
+ (struct sockaddr *) &encapnetmask,
+ RTF_UP | RTF_GATEWAY | RTF_STATIC,
+ (struct rtentry **) 0);
+
/* Add the entry in the routing table */
error = rtrequest(RTM_ADD, (struct sockaddr *) &encapdst,
(struct sockaddr *) &encapgw,
@@ -511,9 +552,47 @@ va_dcl
if (error)
{
delete_flow(flow, tdbp);
+ if (emp->em_ena_flags & ENABLE_FLAG_LOCAL)
+ delete_flow(flow2, tdbp);
SENDERR(error);
}
+ /* If this is a "local" packet flow */
+ if (emp->em_ena_flags & ENABLE_FLAG_LOCAL)
+ {
+ encapdst.sen_ip_src.s_addr = INADDR_ANY;
+ encapnetmask.sen_ip_src.s_addr = INADDR_BROADCAST;
+
+ if (emp->em_ena_flags & ENABLE_FLAG_REPLACE)
+ rtrequest(RTM_DELETE, (struct sockaddr *) &encapdst,
+ (struct sockaddr *) &encapgw,
+ (struct sockaddr *) &encapnetmask,
+ RTF_UP | RTF_GATEWAY | RTF_STATIC,
+ (struct rtentry **) 0);
+
+ error = rtrequest(RTM_ADD, (struct sockaddr *) &encapdst,
+ (struct sockaddr *) &encapgw,
+ (struct sockaddr *) &encapnetmask,
+ RTF_UP | RTF_GATEWAY | RTF_STATIC,
+ (struct rtentry **) 0);
+
+ if (error)
+ {
+ encapdst.sen_ip_src.s_addr = emp->em_ena_isrc.s_addr;
+ encapnetmask.sen_ip_src.s_addr = emp->em_ena_ismask.s_addr;
+
+ rtrequest(RTM_DELETE, (struct sockaddr *) &encapdst,
+ (struct sockaddr *) &encapgw,
+ (struct sockaddr *) &encapnetmask,
+ RTF_UP | RTF_GATEWAY | RTF_STATIC,
+ (struct rtentry **) 0);
+
+ delete_flow(flow, tdbp);
+ delete_flow(flow2, tdbp);
+ SENDERR(error);
+ }
+ }
+
error = 0;
break;
@@ -533,6 +612,18 @@ va_dcl
if (flow == (struct flow *) NULL)
SENDERR(ENOENT);
+ if (emp->em_ena_flags & ENABLE_FLAG_LOCAL)
+ {
+ alts.s_addr = INADDR_ANY;
+ altm.s_addr = INADDR_BROADCAST;
+
+ flow2 = find_flow(alts, altm, emp->em_ena_idst,
+ emp->em_ena_idmask, emp->em_ena_protocol,
+ emp->em_ena_sport, emp->em_ena_dport, tdbp);
+ if (flow2 == (struct flow *) NULL)
+ SENDERR(ENOENT);
+ }
+
/* Setup the encap fields */
encapdst.sen_len = SENT_IP4_LEN;
encapdst.sen_family = AF_ENCAP;
@@ -566,7 +657,7 @@ va_dcl
encapnetmask.sen_dport = 0xffff;
}
- /* Add the entry in the routing table */
+ /* Delete the entry */
error = rtrequest(RTM_DELETE, (struct sockaddr *) &encapdst,
(struct sockaddr *) &encapgw,
(struct sockaddr *) &encapnetmask,
@@ -575,6 +666,27 @@ va_dcl
delete_flow(flow, tdbp);
+ if (error)
+ SENDERR(error);
+
+ if (emp->em_ena_flags & ENABLE_FLAG_LOCAL)
+ {
+
+ encapdst.sen_ip_src.s_addr = INADDR_ANY;
+ encapnetmask.sen_ip_src.s_addr = INADDR_BROADCAST;
+
+ error = rtrequest(RTM_DELETE, (struct sockaddr *) &encapdst,
+ (struct sockaddr *) &encapgw,
+ (struct sockaddr *) &encapnetmask,
+ RTF_UP | RTF_GATEWAY | RTF_STATIC,
+ (struct rtentry **) 0);
+
+ delete_flow(flow2, tdbp);
+
+ if (error)
+ SENDERR(error);
+ }
+
break;
case EMT_NOTIFY:
diff --git a/sys/net/encap.h b/sys/net/encap.h
index 0c4ddf25bf0..8ee2cec21dd 100644
--- a/sys/net/encap.h
+++ b/sys/net/encap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: encap.h,v 1.8 1997/07/14 08:46:40 provos Exp $ */
+/* $OpenBSD: encap.h,v 1.9 1997/07/15 23:11:09 provos Exp $ */
/*
* The author of this code is John Ioannidis, ji@tla.org,
@@ -231,7 +231,7 @@ struct encap_msghdr
u_int16_t Dport; /* Destination port, if applicable */
u_int8_t Protocol; /* Transport mode for which protocol */
u_int8_t Sproto; /* IPsec protocol */
- u_int8_t Foo[2]; /* Alignment */
+ u_int16_t Flags;
} Ena;
/* For general use: (in)validate, delete (chain), reserve */
@@ -245,11 +245,18 @@ struct encap_msghdr
} Eu;
};
-#define ENCAP_MSG_FIXED_LEN (2 * sizeof(u_int32_t))
+#define ENABLE_FLAG_REPLACE 1
+#define ENABLE_FLAG_LOCAL 2
+
+#define ENCAP_MSG_FIXED_LEN (2 * sizeof(u_int32_t))
+
+#define NOTIFY_SOFT_EXPIRE 0 /* Soft expiration of SA */
+#define NOTIFY_HARD_EXPIRE 1 /* Hard expiration of SA */
+#define NOTIFY_REQUEST_SA 2 /* Establish an SA */
-#define NOTIFY_SOFT_EXPIRE 0 /* Soft expiration of SA */
-#define NOTIFY_HARD_EXPIRE 1 /* Hard expiration of SA */
-#define NOTIFY_REQUEST_SA 2 /* Establish an SA */
+#define NOTIFY_SATYPE_CONF 0 /* SA should do encryption */
+#define NOTIFY_SATYPE_AUTH 1 /* SA should do authentication */
+#define NOTIFY_SATYPE_TUNNEL 2 /* SA should use tunneling */
#define em_ena_spi Eu.Ena.Spi
#define em_ena_dst Eu.Ena.Dst
@@ -261,6 +268,7 @@ struct encap_msghdr
#define em_ena_dport Eu.Ena.Dport
#define em_ena_protocol Eu.Ena.Protocol
#define em_ena_sproto Eu.Ena.Sproto
+#define em_ena_flags Eu.Ena.Flags
#define em_gen_spi Eu.Gen.Spi
#define em_gen_dst Eu.Gen.Dst