diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2006-11-24 13:52:15 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2006-11-24 13:52:15 +0000 |
commit | 7fbffbaf7e3799b9cd7a8945cea919cc091ca8d1 (patch) | |
tree | 0cef703fab0b082809c2f9483714feb180bfe502 | |
parent | 2e37005e33b1ab74053f390d46313cbefe2212ad (diff) |
add support to tag ipsec traffic belonging to specific IKE-initiated
phase 2 traffic. this allows policy-based filtering of encrypted and
unencrypted ipsec traffic with pf(4). see ipsec.conf(5) and
isakmpd.conf(5) for details and examples.
this is work in progress and still needs some testing and feedback,
but it is safe to put it in now.
ok hshoexer@
-rw-r--r-- | sbin/ipsecctl/ike.c | 12 | ||||
-rw-r--r-- | sbin/ipsecctl/ipsec.conf.5 | 80 | ||||
-rw-r--r-- | sbin/ipsecctl/ipsecctl.h | 3 | ||||
-rw-r--r-- | sbin/ipsecctl/parse.y | 40 | ||||
-rw-r--r-- | sbin/ipsecctl/pfkdump.c | 14 | ||||
-rw-r--r-- | sbin/isakmpd/ike_auth.c | 8 | ||||
-rw-r--r-- | sbin/isakmpd/ipsec.c | 93 | ||||
-rw-r--r-- | sbin/isakmpd/isakmpd.conf.5 | 37 | ||||
-rw-r--r-- | sbin/isakmpd/pf_key_v2.c | 26 | ||||
-rw-r--r-- | sbin/isakmpd/sa.c | 4 | ||||
-rw-r--r-- | sbin/isakmpd/sa.h | 5 | ||||
-rw-r--r-- | sbin/isakmpd/util.c | 33 | ||||
-rw-r--r-- | sbin/isakmpd/util.h | 3 | ||||
-rw-r--r-- | sys/net/pfkeyv2.c | 31 | ||||
-rw-r--r-- | sys/net/pfkeyv2.h | 13 | ||||
-rw-r--r-- | sys/net/pfkeyv2_convert.c | 37 | ||||
-rw-r--r-- | sys/net/pfkeyv2_parsemessage.c | 33 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.c | 15 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.h | 6 | ||||
-rw-r--r-- | sys/netinet/ipsec_input.c | 14 | ||||
-rw-r--r-- | sys/netinet/ipsec_output.c | 14 |
21 files changed, 481 insertions, 40 deletions
diff --git a/sbin/ipsecctl/ike.c b/sbin/ipsecctl/ike.c index 809a70dcb53..0bc1742c0e5 100644 --- a/sbin/ipsecctl/ike.c +++ b/sbin/ipsecctl/ike.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ike.c,v 1.54 2006/11/24 08:07:18 markus Exp $ */ +/* $OpenBSD: ike.c,v 1.55 2006/11/24 13:52:13 reyk Exp $ */ /* * Copyright (c) 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org> * @@ -39,7 +39,7 @@ static void ike_section_ids(struct ipsec_addr_wrap *, struct ipsec_auth *, FILE *, u_int8_t); static int ike_get_id_type(char *); static void ike_section_ipsec(struct ipsec_addr_wrap *, struct - ipsec_addr_wrap *, struct ipsec_addr_wrap *, FILE *); + ipsec_addr_wrap *, struct ipsec_addr_wrap *, char *, FILE *); static int ike_section_p1(struct ipsec_addr_wrap *, struct ipsec_transforms *, FILE *, struct ike_auth *, u_int8_t); static int ike_section_p2(struct ipsec_addr_wrap *, struct @@ -175,7 +175,7 @@ ike_get_id_type(char *string) static void ike_section_ipsec(struct ipsec_addr_wrap *src, struct ipsec_addr_wrap *dst, - struct ipsec_addr_wrap *peer, FILE *fd) + struct ipsec_addr_wrap *peer, char *tag, FILE *fd) { fprintf(fd, SET "[IPsec-%s-%s]:Phase=2 force\n", src->name, dst->name); @@ -193,6 +193,10 @@ ike_section_ipsec(struct ipsec_addr_wrap *src, struct ipsec_addr_wrap *dst, dst->name, src->name); fprintf(fd, SET "[IPsec-%s-%s]:Remote-ID=rid-%s force\n", src->name, dst->name, dst->name); + + if (tag) + fprintf(fd, SET "[IPsec-%s-%s]:PF-Tag=%s force\n", + src->name, dst->name, tag); } static int @@ -595,7 +599,7 @@ ike_gen_config(struct ipsec_rule *r, FILE *fd) fd, r->ikeauth, r->p1ie) == -1) return (-1); ike_section_ids(r->peer, r->auth, fd, r->ikemode); - ike_section_ipsec(r->src, r->dst, r->peer, fd); + ike_section_ipsec(r->src, r->dst, r->peer, r->tag, fd); if (ike_section_p2(r->src, r->dst, r->satype, r->tmode, r->p2xfs, fd, r->p2ie) == -1) return (-1); diff --git a/sbin/ipsecctl/ipsec.conf.5 b/sbin/ipsecctl/ipsec.conf.5 index 5bc3da99e2f..84cacacba47 100644 --- a/sbin/ipsecctl/ipsec.conf.5 +++ b/sbin/ipsecctl/ipsec.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ipsec.conf.5,v 1.106 2006/11/13 14:42:28 jmc Exp $ +.\" $OpenBSD: ipsec.conf.5,v 1.107 2006/11/24 13:52:13 reyk Exp $ .\" .\" Copyright (c) 2004 Mathieu Sauve-Frankel All rights reserved. .\" @@ -367,6 +367,41 @@ for authentication. If this option is not specified, public key authentication is used (see .Xr isakmpd 8 ) . +.It Ic tag Ar string +Add a +.Xr pf 4 +tag to all packets of phase 2 SAs created for this connection. +This will allow matching packets for this connection by defining +rules in +.Xr pf.conf 5 +using the +.Cm tagged +keyword. +.Pp +The following variables can be used in tags to include information +from the remote peer on runtime: +.Pp +.Bl -tag -width $domain -compact -offset indent +.It Ar $id +The remote phase 1 ID. +It will be expanded to +.Ar id-type/id-value , +e.g.\& +.Ar fqdn/foo.bar.org . +.It Ar $domain +Extract the domain from IDs of type FQDN or UFQDN. +.El +.Pp +For example, if the ID is +.Ar fqdn/foo.bar.org +or +.Ar ufqdn/user@bar.org , +.Dq ipsec-$domain +expands to +.Dq ipsec-bar.org . +The variable expansion for the +.Ar tag +directive occurs only at runtime, not during configuration file parse time. .El .Sh PACKET FILTERING IPsec traffic appears unencrypted on the @@ -397,6 +432,10 @@ and incoming traffic after it's been decapsulated. [tunnel mode only] IP-in-IP traffic flowing between gateways on the enc0 interface. +.It tagged ipsec-example.org +Match traffic of phase 2 SAs using the +.Ic tag +keyword. .El .Pp If the filtering rules specify to block everything by default, @@ -447,6 +486,45 @@ to avoid permitting unencrypted traffic should exit. Therefore all rules on the enc0 interface should explicitly set .Dq keep state (if-bound) . +.Pp +.Xr pf 4 +has the ability to filter IPsec-related packets +based on an arbitrary +.Em tag +specified within a ruleset. +The tag is used as an internal marker +which can be used to identify the packets later on. +This could be helpful, +for example, +in scenarios where users are connecting in from differing IP addresses, +or to support queue-based bandwidth control, +since the enc0 interface does not support it. +.Pp +The following +.Xr pf.conf 5 +fragment uses queues for all IPsec traffic with special +handling for developers and employees: +.Bd -literal -offset indent +altq on sk0 cbq bandwidth 1000Mb \e + queue { deflt, developers, employees, ipsec } + queue deflt bandwidth 10% priority 0 cbq(default ecn) + queue developers bandwidth 75% priority 7 cbq(borrow red) + queue employees bandwidth 5% cbq(red) + queue ipsec bandwidth 10% cbq(red) + +pass out on sk0 proto esp queue ipsec + +pass out on sk0 tagged ipsec-developers.bar.org queue developers +pass out on sk0 tagged ipsec-employees.bar.org queue employees +.Ed +.Pp +The tags will be assigned by the following +.Nm +example: +.Bd -literal -offset indent +ike esp from 10.1.1.0/24 to 10.1.2.0/24 peer 192.168.3.2 \e + tag ipsec-$domain +.Ed .Sh CRYPTO TRANSFORMS It is very important that keys are not guessable. One practical way of generating keys is to use diff --git a/sbin/ipsecctl/ipsecctl.h b/sbin/ipsecctl/ipsecctl.h index 27e84bd5850..fac2fee8882 100644 --- a/sbin/ipsecctl/ipsecctl.h +++ b/sbin/ipsecctl/ipsecctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsecctl.h,v 1.50 2006/11/01 03:10:02 mcbride Exp $ */ +/* $OpenBSD: ipsecctl.h,v 1.51 2006/11/24 13:52:13 reyk Exp $ */ /* * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org> * @@ -181,6 +181,7 @@ struct ipsec_rule { struct ipsec_key *authkey; struct ipsec_key *enckey; + char *tag; /* pf tag for SAs */ u_int8_t satype; /* encapsulating prococol */ u_int8_t proto; /* encapsulated protocol */ u_int8_t proto2; diff --git a/sbin/ipsecctl/parse.y b/sbin/ipsecctl/parse.y index f4891460007..7cd73f11173 100644 --- a/sbin/ipsecctl/parse.y +++ b/sbin/ipsecctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.113 2006/11/13 11:04:05 mcbride Exp $ */ +/* $OpenBSD: parse.y,v 1.114 2006/11/24 13:52:13 reyk Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -154,6 +154,7 @@ struct ipsec_auth *copyipsecauth(const struct ipsec_auth *); struct ike_auth *copyikeauth(const struct ike_auth *); struct ipsec_key *copykey(struct ipsec_key *); struct ipsec_addr_wrap *copyhost(const struct ipsec_addr_wrap *); +char *copytag(const char *); struct ipsec_rule *copyrule(struct ipsec_rule *); int validate_af(struct ipsec_addr_wrap *, struct ipsec_addr_wrap *); @@ -178,7 +179,7 @@ struct ipsec_rule *reverse_rule(struct ipsec_rule *); struct ipsec_rule *create_ike(u_int8_t, struct ipsec_hosts *, struct ipsec_hosts *, struct ike_mode *, struct ike_mode *, u_int8_t, u_int8_t, u_int8_t, - char *, char *, struct ike_auth *); + char *, char *, struct ike_auth *, char *); int add_sagroup(struct ipsec_rule *); struct ipsec_transforms *ipsec_transforms; @@ -232,7 +233,7 @@ typedef struct { %token FLOW FROM ESP AH IN PEER ON OUT TO SRCID DSTID RSA PSK TCPMD5 SPI %token AUTHKEY ENCKEY FILENAME AUTHXF ENCXF ERROR IKE MAIN QUICK AGGRESSIVE %token PASSIVE ACTIVE ANY IPIP IPCOMP COMPXF TUNNEL TRANSPORT DYNAMIC LIFE -%token TYPE DENY BYPASS LOCAL PROTO USE ACQUIRE REQUIRE DONTACQ GROUP PORT +%token TYPE DENY BYPASS LOCAL PROTO USE ACQUIRE REQUIRE DONTACQ GROUP PORT TAG %token <v.string> STRING %type <v.string> string %type <v.dir> dir @@ -257,6 +258,7 @@ typedef struct { %type <v.type> type %type <v.life> life %type <v.mode> phase1mode phase2mode +%type <v.string> tag %% grammar : /* empty */ @@ -332,11 +334,11 @@ flowrule : FLOW satype dir proto hosts peers ids type { ; ikerule : IKE ikemode satype tmode proto hosts peers - phase1mode phase2mode ids ikeauth { + phase1mode phase2mode ids ikeauth tag { struct ipsec_rule *r; r = create_ike($5, &$6, &$7, $8, $9, $3, $4, $2, - $10.srcid, $10.dstid, &$11); + $10.srcid, $10.dstid, &$11, $12); if (r == NULL) YYERROR; @@ -774,6 +776,16 @@ ikeauth : /* empty */ { } ; +tag : /* empty */ + { + $$ = NULL; + } + | TAG STRING + { + $$ = $2; + } + ; + string : string STRING { if (asprintf(&$$, "%s %s", $1, $2) == -1) @@ -866,6 +878,7 @@ lookup(char *s) { "rsa", RSA }, { "spi", SPI }, { "srcid", SRCID }, + { "tag", TAG }, { "tcpmd5", TCPMD5 }, { "to", TO }, { "transport", TRANSPORT }, @@ -1799,6 +1812,19 @@ copyhost(const struct ipsec_addr_wrap *src) return dst; } +char * +copytag(const char *src) +{ + char *tag; + + if (src == NULL) + return (NULL); + if ((tag = strdup(src)) == NULL) + err(1, "copytag: strdup"); + + return (tag); +} + struct ipsec_rule * copyrule(struct ipsec_rule *rule) { @@ -1820,6 +1846,7 @@ copyrule(struct ipsec_rule *rule) r->p2life = copylife(rule->p2life); r->authkey = copykey(rule->authkey); r->enckey = copykey(rule->enckey); + r->tag = copytag(rule->tag); r->p1ie = rule->p1ie; r->p2ie = rule->p2ie; @@ -2304,7 +2331,7 @@ struct ipsec_rule * create_ike(u_int8_t proto, struct ipsec_hosts *hosts, struct ipsec_hosts *peers, struct ike_mode *phase1mode, struct ike_mode *phase2mode, u_int8_t satype, u_int8_t tmode, u_int8_t mode, char *srcid, char *dstid, - struct ike_auth *authtype) + struct ike_auth *authtype, char *tag) { struct ipsec_rule *r; @@ -2394,6 +2421,7 @@ create_ike(u_int8_t proto, struct ipsec_hosts *hosts, struct ipsec_hosts *peers, err(1, "create_ike: calloc"); r->ikeauth->type = authtype->type; r->ikeauth->string = authtype->string; + r->tag = tag; return (r); } diff --git a/sbin/ipsecctl/pfkdump.c b/sbin/ipsecctl/pfkdump.c index 18c04750031..461ec13882b 100644 --- a/sbin/ipsecctl/pfkdump.c +++ b/sbin/ipsecctl/pfkdump.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkdump.c,v 1.22 2006/09/19 21:29:47 markus Exp $ */ +/* $OpenBSD: pfkdump.c,v 1.23 2006/11/24 13:52:13 reyk Exp $ */ /* * Copyright (c) 2003 Markus Friedl. All rights reserved. @@ -55,6 +55,7 @@ static void print_ident(struct sadb_ext *, struct sadb_msg *); static void print_auth(struct sadb_ext *, struct sadb_msg *); static void print_cred(struct sadb_ext *, struct sadb_msg *); static void print_udpenc(struct sadb_ext *, struct sadb_msg *); +static void print_tag(struct sadb_ext *, struct sadb_msg *); static struct idname *lookup(struct idname [], u_int8_t); static char *lookup_name(struct idname [], u_int8_t); @@ -104,6 +105,7 @@ struct idname ext_types[] = { { SADB_X_EXT_REMOTE_CREDENTIALS,"remote_cred", print_cred }, { SADB_X_EXT_UDPENCAP, "udpencap", print_udpenc }, { SADB_X_EXT_LIFETIME_LASTUSE, "lifetime_lastuse", print_life }, + { SADB_X_EXT_TAG, "tag", print_tag }, { 0, NULL, NULL } }; @@ -374,6 +376,16 @@ print_flow(struct sadb_ext *ext, struct sadb_msg *msg) lookup_name(flow_types, proto->sadb_protocol_proto), dir); } +static void +print_tag(struct sadb_ext *ext, struct sadb_msg *msg) +{ + struct sadb_x_tag *stag = (struct sadb_x_tag *)ext; + char *p; + + p = (char *)(stag + 1); + printf("%s", p); +} + static char * alg_by_ext(u_int8_t ext_type, u_int8_t id) { diff --git a/sbin/isakmpd/ike_auth.c b/sbin/isakmpd/ike_auth.c index 7d017da260e..9395cdde77b 100644 --- a/sbin/isakmpd/ike_auth.c +++ b/sbin/isakmpd/ike_auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ike_auth.c,v 1.108 2006/11/09 09:43:35 markus Exp $ */ +/* $OpenBSD: ike_auth.c,v 1.109 2006/11/24 13:52:14 reyk Exp $ */ /* $EOM: ike_auth.c,v 1.59 2000/11/21 00:21:31 angelos Exp $ */ /* @@ -910,12 +910,14 @@ rsa_sig_encode_hash(struct message *msg) if (handler->cert_obtain(id, id_len, 0, &data, &datalen) == 0) { LOG_DBG((LOG_MISC, 10, "rsa_sig_encode_hash: " - "no certificate to send")); + "no certificate to send for id %s", + ipsec_id_string(id, id_len))); goto skipcert; } } else { LOG_DBG((LOG_MISC, 10, - "rsa_sig_encode_hash: no certificate to send")); + "rsa_sig_encode_hash: no certificate to send" + " for id %s", ipsec_id_string(id, id_len))); goto skipcert; } } diff --git a/sbin/isakmpd/ipsec.c b/sbin/isakmpd/ipsec.c index ab8bbaba787..e53406e1e89 100644 --- a/sbin/isakmpd/ipsec.c +++ b/sbin/isakmpd/ipsec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec.c,v 1.126 2006/06/10 20:10:02 hshoexer Exp $ */ +/* $OpenBSD: ipsec.c,v 1.127 2006/11/24 13:52:14 reyk Exp $ */ /* $EOM: ipsec.c,v 1.143 2000/12/11 23:57:42 niklas Exp $ */ /* @@ -39,6 +39,9 @@ #include <stdlib.h> #include <string.h> +#include <net/if.h> +#include <net/pfvar.h> + #include "sysdep.h" #include "attribute.h" @@ -129,6 +132,7 @@ static int ipsec_validate_notification(u_int16_t); static int ipsec_validate_proto(u_int8_t); static int ipsec_validate_situation(u_int8_t *, size_t *, size_t); static int ipsec_validate_transform_id(u_int8_t, u_int8_t); +static int ipsec_sa_tag(struct exchange *, struct sa *, struct sa *); static struct doi ipsec_doi = { {0}, IPSEC_DOI_IPSEC, @@ -277,6 +281,90 @@ ipsec_sa_check_flow(struct sa *sa, void *v_arg) } /* + * Construct a PF tag if specified in the configuration. + * It is possible to use variables to expand the tag: + * $id The string representation of the remote ID + * $domain The stripped domain part of the ID (for FQDN and UFQDN) + */ +static int +ipsec_sa_tag(struct exchange *exchange, struct sa *sa, struct sa *isakmp_sa) +{ + char *format, *section; + char *id_string = NULL, *domain = NULL; + int error = -1; + size_t len; + + sa->tag = NULL; + + if (exchange->name == NULL || + (section = exchange->name) == NULL || + (format = conf_get_str(section, "PF-Tag")) == NULL) + return (0); /* ignore if not present */ + + len = PF_TAG_NAME_SIZE; + if ((sa->tag = calloc(1, len)) == NULL) { + log_error("ipsec_sa_tag: calloc"); + goto fail; + } + if (strlcpy(sa->tag, format, len) >= len) { + log_print("ipsec_sa_tag: tag too long"); + goto fail; + } + if (isakmp_sa->initiator) + id_string = ipsec_id_string(isakmp_sa->id_r, + isakmp_sa->id_r_len); + else + id_string = ipsec_id_string(isakmp_sa->id_i, + isakmp_sa->id_i_len); + + if (strstr(format, "$id") != NULL) { + if (id_string == NULL) { + log_print("ipsec_sa_tag: cannot get ID"); + goto fail; + } + if (expand_string(sa->tag, len, "$id", id_string) != 0) { + log_print("ipsec_sa_tag: failed to expand tag"); + goto fail; + } + } + + if (strstr(format, "$domain") != NULL) { + if (id_string == NULL) { + log_print("ipsec_sa_tag: cannot get ID"); + goto fail; + } + if (strncmp(id_string, "fqdn/", strlen("fqdn/")) == 0) + domain = strchr(id_string, '.'); + else if (strncmp(id_string, "ufqdn/", strlen("ufqdn/")) == 0) + domain = strchr(id_string, '@'); + if (domain == NULL || strlen(domain) < 2) { + log_print("ipsec_sa_tag: no valid domain in ID %s", + id_string); + goto fail; + } + domain++; + if (expand_string(sa->tag, len, "$domain", domain) != 0) { + log_print("ipsec_sa_tag: failed to expand tag"); + goto fail; + } + } + + LOG_DBG((LOG_SA, 10, "ipsec_sa_tag: tag_len %ld tag \"%s\"", + strlen(sa->tag), sa->tag)); + + error = 0; + fail: + if (id_string != NULL) + free(id_string); + if (error != 0 && sa->tag != NULL) { + free(sa->tag); + sa->tag = NULL; + } + + return (error); +} + +/* * Do IPsec DOI specific finalizations task for the exchange where MSG was * the final message. */ @@ -357,6 +445,9 @@ ipsec_finalize_exchange(struct message *msg) } } + if (ipsec_sa_tag(exchange, sa, isakmp_sa) == -1) + return; + for (proto = TAILQ_FIRST(&sa->protos), last_proto = 0; proto; proto = TAILQ_NEXT(proto, link)) { diff --git a/sbin/isakmpd/isakmpd.conf.5 b/sbin/isakmpd/isakmpd.conf.5 index 657aa776f56..06c71c7fdf9 100644 --- a/sbin/isakmpd/isakmpd.conf.5 +++ b/sbin/isakmpd/isakmpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: isakmpd.conf.5,v 1.118 2006/09/15 09:49:07 hshoexer Exp $ +.\" $OpenBSD: isakmpd.conf.5,v 1.119 2006/11/24 13:52:14 reyk Exp $ .\" $EOM: isakmpd.conf.5,v 1.57 2000/12/21 14:43:17 ho Exp $ .\" .\" Copyright (c) 1998, 1999, 2000 Niklas Hallqvist. All rights reserved. @@ -647,6 +647,41 @@ we are dealing with. Look at .Aq Sy IPsec-ID below. +.It Em PF-Tag +Add a +.Xr pf 4 +tag to all packets of phase 2 SAs created for this connection. +This will allow matching packets for this connection by defining +rules in +.Xr pf.conf 5 +using the +.Em tagged +keyword. +.Pp +The following variables can be used in tags to include information +from the remote peer on runtime: +.Pp +.Bl -tag -width $domain -compact -offset indent +.It Ar $id +The remote phase 1 ID. +It will be expanded to +.Ar id-type/id-value , +e.g.\& +.Ar fqdn/foo.bar.org . +.It Ar $domain +Extract the domain from IDs of type FQDN or UFQDN. +.El +.Pp +For example, if the ID is +.Ar fqdn/foo.bar.org +or +.Ar ufqdn/user@bar.org , +.Dq PF-Tag=ipsec-$domain +expands to +.Dq ipsec-bar.org . +The variable expansion for the +.Ar PF-Tag +directive occurs only at runtime, not during configuration file parse time. .El .It Aq Sy IPsec-configuration Parameters for IPsec configuration diff --git a/sbin/isakmpd/pf_key_v2.c b/sbin/isakmpd/pf_key_v2.c index 77e6abb9752..15b7cc104e7 100644 --- a/sbin/isakmpd/pf_key_v2.c +++ b/sbin/isakmpd/pf_key_v2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_key_v2.c,v 1.176 2006/09/01 00:24:06 mpf Exp $ */ +/* $OpenBSD: pf_key_v2.c,v 1.177 2006/11/24 13:52:14 reyk Exp $ */ /* $EOM: pf_key_v2.c,v 1.79 2000/12/12 00:33:19 niklas Exp $ */ /* @@ -902,6 +902,7 @@ pf_key_v2_set_spi(struct sa *sa, struct proto *proto, int incoming, { struct sadb_msg msg; struct sadb_sa ssa; + struct sadb_x_tag *stag = NULL; struct sadb_lifetime *life = 0; struct sadb_address *addr = 0; struct sadb_key *key = 0; @@ -917,7 +918,7 @@ pf_key_v2_set_spi(struct sa *sa, struct proto *proto, int incoming, struct sadb_x_cred *cred; struct sadb_protocol flowtype, tprotocol; struct sadb_x_udpencap udpencap; - char *addr_str; + char *addr_str, *s; msg.sadb_msg_type = incoming ? SADB_UPDATE : SADB_ADD; switch (proto->proto) { @@ -1549,14 +1550,31 @@ doneauth: goto cleanup; addr = 0; + /* Add a pf tag to matching packets of this SA. */ + if (sa->tag != NULL) { + len = sizeof(*stag) + PF_KEY_V2_ROUND(strlen(sa->tag) + 1); + if ((stag = (struct sadb_x_tag *)calloc(1, len)) == NULL) + goto cleanup; + stag->sadb_x_tag_exttype = SADB_X_EXT_TAG; + stag->sadb_x_tag_len = len / PF_KEY_V2_CHUNK; + stag->sadb_x_tag_taglen = strlen(sa->tag) + 1; + s = (char *)(stag + 1); + strlcpy(s, sa->tag, stag->sadb_x_tag_taglen); + if (pf_key_v2_msg_add(update, (struct sadb_ext *)stag, + PF_KEY_V2_NODE_MALLOCED) == -1) + goto cleanup; + } + /* XXX Here can sensitivity extensions be setup. */ if (sockaddr2text(dst, &addr_str, 0)) addr_str = 0; LOG_DBG((LOG_SYSDEP, 10, "pf_key_v2_set_spi: " - "satype %d dst %s SPI 0x%x", msg.sadb_msg_satype, - addr_str ? addr_str : "unknown", ntohl(ssa.sadb_sa_spi))); + "satype %d dst %s SPI 0x%x%s%s", msg.sadb_msg_satype, + addr_str ? addr_str : "unknown", + ntohl(ssa.sadb_sa_spi), sa->tag ? " tag " : "", + sa->tag ? sa->tag : "")); if (addr_str) free(addr_str); diff --git a/sbin/isakmpd/sa.c b/sbin/isakmpd/sa.c index 7e2e88e9411..4e73b95ed5f 100644 --- a/sbin/isakmpd/sa.c +++ b/sbin/isakmpd/sa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sa.c,v 1.109 2006/08/30 16:33:31 cloder Exp $ */ +/* $OpenBSD: sa.c,v 1.110 2006/11/24 13:52:14 reyk Exp $ */ /* $EOM: sa.c,v 1.112 2000/12/12 00:22:52 niklas Exp $ */ /* @@ -868,6 +868,8 @@ sa_release(struct sa *sa) timer_remove_event(sa->dpd_event); if (sa->transport) transport_release(sa->transport); + if (sa->tag) + free(sa->tag); free(sa); } diff --git a/sbin/isakmpd/sa.h b/sbin/isakmpd/sa.h index a6f1305f5d8..02bb4faa897 100644 --- a/sbin/isakmpd/sa.h +++ b/sbin/isakmpd/sa.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sa.h,v 1.48 2006/06/02 19:35:55 hshoexer Exp $ */ +/* $OpenBSD: sa.h,v 1.49 2006/11/24 13:52:14 reyk Exp $ */ /* $EOM: sa.h,v 1.58 2000/10/10 12:39:01 provos Exp $ */ /* @@ -209,6 +209,9 @@ struct sa { u_int32_t dpd_failcount; /* # of subsequent failures */ u_int32_t dpd_rdupcount; /* # of subsequent duplicates */ struct event *dpd_event; /* time of next event */ + + /* The add a pf tag to packets matching the established SA. */ + char *tag; }; /* This SA is alive. */ diff --git a/sbin/isakmpd/util.c b/sbin/isakmpd/util.c index 41442693747..5ca25daee32 100644 --- a/sbin/isakmpd/util.c +++ b/sbin/isakmpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.62 2006/07/24 11:45:44 ho Exp $ */ +/* $OpenBSD: util.c,v 1.63 2006/11/24 13:52:14 reyk Exp $ */ /* $EOM: util.c,v 1.23 2000/11/23 12:22:08 niklas Exp $ */ /* @@ -621,3 +621,34 @@ gc_strdup(const char *x) return strcpy(y,x); } #endif + +int +expand_string(char *label, size_t len, const char *srch, const char *repl) +{ + char *tmp; + char *p, *q; + + if ((tmp = calloc(1, len)) == NULL) { + log_error("expand_string: calloc"); + return (-1); + } + p = q = label; + while ((q = strstr(p, srch)) != NULL) { + *q = '\0'; + if ((strlcat(tmp, p, len) >= len) || + (strlcat(tmp, repl, len) >= len)) { + log_print("expand_string: string too long"); + return (-1); + } + q += strlen(srch); + p = q; + } + if (strlcat(tmp, p, len) >= len) { + log_print("expand_string: string too long"); + return (-1); + } + strlcpy(label, tmp, len); /* always fits */ + free(tmp); + + return (0); +} diff --git a/sbin/isakmpd/util.h b/sbin/isakmpd/util.h index f466a360d71..d09d8917213 100644 --- a/sbin/isakmpd/util.h +++ b/sbin/isakmpd/util.h @@ -1,4 +1,4 @@ -/* $OpenBSD: util.h,v 1.28 2005/12/28 10:57:35 hshoexer Exp $ */ +/* $OpenBSD: util.h,v 1.29 2006/11/24 13:52:14 reyk Exp $ */ /* $EOM: util.h,v 1.10 2000/10/24 13:33:39 niklas Exp $ */ /* @@ -63,5 +63,6 @@ extern int text2sockaddr(char *, char *, struct sockaddr **, extern void util_ntoa(char **, int, u_int8_t *); extern int zero_test(const u_int8_t *, size_t); extern long get_timeout(struct timeval *); +extern int expand_string(char *, size_t, const char *, const char *); #endif /* _UTIL_H_ */ diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c index 418d72cf351..fa8fb91aea1 100644 --- a/sys/net/pfkeyv2.c +++ b/sys/net/pfkeyv2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2.c,v 1.111 2006/06/16 16:49:39 henning Exp $ */ +/* $OpenBSD: pfkeyv2.c,v 1.112 2006/11/24 13:52:14 reyk Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 @@ -68,6 +68,8 @@ * SUCH DAMAGE. */ +#include "pf.h" + #include <sys/types.h> #include <sys/param.h> #include <sys/socket.h> @@ -83,6 +85,11 @@ #include <netinet/ip_ipcomp.h> #include <crypto/blf.h> +#if NPF > 0 +#include <net/if.h> +#include <net/pfvar.h> +#endif + #define PFKEYV2_PROTOCOL 2 #define GETSPI_TRIES 10 @@ -552,6 +559,11 @@ pfkeyv2_get(struct tdb *sa, void **headers, void **buffer, int *lenp) if (sa->tdb_udpencap_port) i+= sizeof(struct sadb_x_udpencap); +#if NPF > 0 + if (sa->tdb_tag) + i+= PADUP(PF_TAG_NAME_SIZE) + sizeof(struct sadb_x_tag); +#endif + if (lenp) *lenp = i; @@ -659,6 +671,14 @@ pfkeyv2_get(struct tdb *sa, void **headers, void **buffer, int *lenp) export_udpencap(&p, sa); } +#if NPF > 0 + /* Export tag information, if present */ + if (sa->tdb_tag) { + headers[SADB_X_EXT_TAG] = p; + export_tag(&p, sa); + } +#endif + rval = 0; ret: @@ -1005,6 +1025,9 @@ pfkeyv2_send(struct socket *socket, void *message, int len) headers[SADB_X_EXT_PROTOCOL], headers[SADB_X_EXT_FLOW_TYPE]); import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]); +#if NPF > 0 + import_tag(newsa, headers[SADB_X_EXT_TAG]); +#endif headers[SADB_EXT_KEY_AUTH] = NULL; headers[SADB_EXT_KEY_ENCRYPT] = NULL; @@ -1051,6 +1074,9 @@ pfkeyv2_send(struct socket *socket, void *message, int len) import_lifetime(sa2, headers[SADB_EXT_LIFETIME_HARD], PFKEYV2_LIFETIME_HARD); import_udpencap(sa2, headers[SADB_X_EXT_UDPENCAP]); +#if NPF > 0 + import_tag(sa2, headers[SADB_X_EXT_TAG]); +#endif } splx(s); @@ -1163,6 +1189,9 @@ pfkeyv2_send(struct socket *socket, void *message, int len) headers[SADB_X_EXT_PROTOCOL], headers[SADB_X_EXT_FLOW_TYPE]); import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]); +#if NPF > 0 + import_tag(newsa, headers[SADB_X_EXT_TAG]); +#endif headers[SADB_EXT_KEY_AUTH] = NULL; headers[SADB_EXT_KEY_ENCRYPT] = NULL; diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h index a0510204658..64b28b5daa7 100644 --- a/sys/net/pfkeyv2.h +++ b/sys/net/pfkeyv2.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2.h,v 1.55 2005/05/27 15:29:55 hshoexer Exp $ */ +/* $OpenBSD: pfkeyv2.h,v 1.56 2006/11/24 13:52:14 reyk Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) January 1998 * @@ -213,6 +213,12 @@ struct sadb_x_udpencap { uint16_t sadb_x_udpencap_reserved; }; +struct sadb_x_tag { + uint16_t sadb_x_tag_len; + uint16_t sadb_x_tag_exttype; + u_int32_t sadb_x_tag_taglen; +}; + #ifdef _KERNEL #define SADB_X_GETSPROTO(x) \ ( (x) == SADB_SATYPE_AH ? IPPROTO_AH :\ @@ -254,7 +260,8 @@ struct sadb_x_udpencap { #define SADB_X_EXT_SUPPORTED_COMP 30 #define SADB_X_EXT_UDPENCAP 31 #define SADB_X_EXT_LIFETIME_LASTUSE 32 -#define SADB_EXT_MAX 32 +#define SADB_X_EXT_TAG 33 +#define SADB_EXT_MAX 33 /* Fix pfkeyv2.c struct pfkeyv2_socket if SATYPE_MAX > 31 */ #define SADB_SATYPE_UNSPEC 0 @@ -445,6 +452,7 @@ void export_flow(void **, u_int8_t, struct sockaddr_encap *, void export_key(void **, struct tdb *, int); void export_auth(void **, struct tdb *, int); void export_udpencap(void **, struct tdb *); +void export_tag(void **, struct tdb *); void import_auth(struct tdb *, struct sadb_x_cred *, int); void import_address(struct sockaddr *, struct sadb_address *); @@ -457,5 +465,6 @@ void import_flow(struct sockaddr_encap *, struct sockaddr_encap *, struct sadb_address *, struct sadb_address *, struct sadb_address *, struct sadb_address *, struct sadb_protocol *, struct sadb_protocol *); void import_udpencap(struct tdb *, struct sadb_x_udpencap *); +void import_tag(struct tdb *, struct sadb_x_tag *); #endif /* _KERNEL */ #endif /* _NET_PFKEY_V2_H_ */ diff --git a/sys/net/pfkeyv2_convert.c b/sys/net/pfkeyv2_convert.c index e9bad2393b2..baa61c0a90e 100644 --- a/sys/net/pfkeyv2_convert.c +++ b/sys/net/pfkeyv2_convert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2_convert.c,v 1.28 2006/06/01 07:06:09 todd Exp $ */ +/* $OpenBSD: pfkeyv2_convert.c,v 1.29 2006/11/24 13:52:14 reyk Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@keromytis.org) * @@ -91,6 +91,8 @@ * SUCH DAMAGE. */ +#include "pf.h" + #include <sys/types.h> #include <sys/param.h> #include <sys/systm.h> @@ -99,6 +101,11 @@ #include <sys/socket.h> #include <net/route.h> #include <net/if.h> + +#if NPF > 0 +#include <net/pfvar.h> +#endif + #include <netinet/ip_ipsp.h> #ifdef INET6 #include <netinet6/in6_var.h> @@ -973,3 +980,31 @@ export_udpencap(void **p, struct tdb *tdb) sizeof(struct sadb_x_udpencap) / sizeof(uint64_t); *p += sizeof(struct sadb_x_udpencap); } + +#if NPF > 0 +/* Import PF tag information for SA */ +void +import_tag(struct tdb *tdb, struct sadb_x_tag *stag) +{ + char *s; + + if (stag) { + s = (char *)(stag + 1); + tdb->tdb_tag = pf_tagname2tag(s); + } +} + +/* Export PF tag information for SA */ +void +export_tag(void **p, struct tdb *tdb) +{ + struct sadb_x_tag *stag = (struct sadb_x_tag *)*p; + char *s = (char *)(stag + 1); + + pf_tag2tagname(tdb->tdb_tag, s); + stag->sadb_x_tag_taglen = strlen(s) + 1; + stag->sadb_x_tag_len = (sizeof(struct sadb_x_tag) + + PADUP(stag->sadb_x_tag_taglen)) / sizeof(uint64_t); + *p += PADUP(stag->sadb_x_tag_taglen) + sizeof(struct sadb_x_tag); +} +#endif diff --git a/sys/net/pfkeyv2_parsemessage.c b/sys/net/pfkeyv2_parsemessage.c index 54df2430a79..9018fcfbc86 100644 --- a/sys/net/pfkeyv2_parsemessage.c +++ b/sys/net/pfkeyv2_parsemessage.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2_parsemessage.c,v 1.40 2005/05/28 15:10:07 ho Exp $ */ +/* $OpenBSD: pfkeyv2_parsemessage.c,v 1.41 2006/11/24 13:52:14 reyk Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 @@ -68,6 +68,8 @@ * SUCH DAMAGE. */ +#include "pf.h" + #include <sys/param.h> #include <sys/systm.h> #include <sys/socket.h> @@ -76,6 +78,11 @@ #include <netinet/ip_ipsp.h> #include <net/pfkeyv2.h> +#if NPF > 0 +#include <net/if.h> +#include <net/pfvar.h> +#endif + extern int encdebug; #ifdef ENCDEBUG @@ -123,6 +130,7 @@ extern int encdebug; #define BITMAP_X_SUPPORTED_COMP (1LL << SADB_X_EXT_SUPPORTED_COMP) #define BITMAP_X_UDPENCAP (1LL << SADB_X_EXT_UDPENCAP) #define BITMAP_X_LIFETIME_LASTUSE (1LL << SADB_X_EXT_LIFETIME_LASTUSE) +#define BITMAP_X_TAG (1LL << SADB_X_EXT_TAG) uint64_t sadb_exts_allowed_in[SADB_MAX+1] = { @@ -131,9 +139,9 @@ uint64_t sadb_exts_allowed_in[SADB_MAX+1] = /* GETSPI */ BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE, /* UPDATE */ - BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP, + BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG, /* ADD */ - BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE, + BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_TAG, /* DELETE */ BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, /* GET */ @@ -203,9 +211,9 @@ uint64_t sadb_exts_allowed_out[SADB_MAX+1] = /* GETSPI */ BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, /* UPDATE */ - BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP, + BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG, /* ADD */ - BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP, + BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG, /* DELETE */ BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, /* GET */ @@ -933,6 +941,21 @@ pfkeyv2_parsemessage(void *p, int len, void **headers) return (EINVAL); } break; +#if NPF > 0 + case SADB_X_EXT_TAG: + if (i < sizeof(struct sadb_x_tag)) { + DPRINTF(("pfkeyv2_parsemessage: " + "TAG extension header too small")); + return (EINVAL); + } + if (i > (sizeof(struct sadb_x_tag) + + PF_TAG_NAME_SIZE)) { + DPRINTF(("pfkeyv2_parsemessage: " + "TAG extension header too long")); + return (EINVAL); + } + break; +#endif default: DPRINTF(("pfkeyv2_parsemessage: unknown extension " "header type %d\n", diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c index 39611a04eed..196aab812f7 100644 --- a/sys/netinet/ip_ipsp.c +++ b/sys/netinet/ip_ipsp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.c,v 1.165 2006/01/13 10:11:23 mpf Exp $ */ +/* $OpenBSD: ip_ipsp.c,v 1.166 2006/11/24 13:52:14 reyk Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr), @@ -37,6 +37,8 @@ * PURPOSE. */ +#include "pf.h" + #include <sys/param.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -46,6 +48,10 @@ #include <net/if.h> #include <net/route.h> +#if NPF > 0 +#include <net/pfvar.h> +#endif + #ifdef INET #include <netinet/in.h> #include <netinet/in_systm.h> @@ -858,6 +864,13 @@ tdb_free(struct tdb *tdbp) tdbp->tdb_remote_cred = NULL; } +#if NPF > 0 + if (tdbp->tdb_tag) { + pf_tag_unref(tdbp->tdb_tag); + tdbp->tdb_tag = 0; + } +#endif + if ((tdbp->tdb_onext) && (tdbp->tdb_onext->tdb_inext == tdbp)) tdbp->tdb_onext->tdb_inext = NULL; diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index 9f0cba75b4f..06fcc70f549 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.h,v 1.134 2006/06/30 21:41:12 deraadt Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.135 2006/11/24 13:52:14 reyk Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr), @@ -270,7 +270,7 @@ struct tdb { /* tunnel descriptor block */ * Each TDB is on three hash tables: one keyed on dst/spi/sproto, * one keyed on dst/sproto, and one keyed on src/sproto. The first * is used for finding a specific TDB, the second for finding TDBs - * TDBs for outgoing policy matching, and the third for incoming + * for outgoing policy matching, and the third for incoming * policy matching. The following three fields maintain the hash * queues in those three tables. */ @@ -367,6 +367,8 @@ struct tdb { /* tunnel descriptor block */ u_int16_t tdb_udpencap_port; /* Peer UDP port */ + u_int16_t tdb_tag; /* Packet filter tag */ + struct sockaddr_encap tdb_filter; /* What traffic is acceptable */ struct sockaddr_encap tdb_filtermask; /* And the mask */ diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c index 2617482c6b2..e00cf80b590 100644 --- a/sys/netinet/ipsec_input.c +++ b/sys/netinet/ipsec_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec_input.c,v 1.79 2006/03/25 22:41:48 djm Exp $ */ +/* $OpenBSD: ipsec_input.c,v 1.80 2006/11/24 13:52:14 reyk Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -35,6 +35,8 @@ * PURPOSE. */ +#include "pf.h" + #include <sys/param.h> #include <sys/systm.h> #include <sys/protosw.h> @@ -47,6 +49,10 @@ #include <net/netisr.h> #include <net/bpf.h> +#if NPF > 0 +#include <net/pfvar.h> +#endif + #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> @@ -554,6 +560,12 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff, } else if (sproto == IPPROTO_AH) m->m_flags |= M_AUTH | M_AUTH_AH; +#if NPF > 0 + /* Add pf tag if requested. */ + if (pf_tag_packet(m, NULL, tdbp->tdb_tag, -1)) + DPRINTF(("failed to tag ipsec packet\n")); +#endif + if (tdbp->tdb_flags & TDBF_TUNNELING) m->m_flags |= M_TUNNEL; diff --git a/sys/netinet/ipsec_output.c b/sys/netinet/ipsec_output.c index 73bae9676d9..1e91a4997ac 100644 --- a/sys/netinet/ipsec_output.c +++ b/sys/netinet/ipsec_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec_output.c,v 1.33 2005/04/12 09:39:54 markus Exp $ */ +/* $OpenBSD: ipsec_output.c,v 1.34 2006/11/24 13:52:14 reyk Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) * @@ -20,6 +20,8 @@ * PURPOSE. */ +#include "pf.h" + #include <sys/param.h> #include <sys/systm.h> #include <sys/mbuf.h> @@ -29,6 +31,10 @@ #include <net/if.h> #include <net/route.h> +#if NPF > 0 +#include <net/pfvar.h> +#endif + #ifdef INET #include <netinet/in.h> #include <netinet/in_systm.h> @@ -428,6 +434,12 @@ ipsp_process_done(struct mbuf *m, struct tdb *tdb) return ipsp_process_packet(m, tdb->tdb_onext, tdb->tdb_dst.sa.sa_family, 0); +#if NPF > 0 + /* Add pf tag if requested. */ + if (pf_tag_packet(m, NULL, tdb->tdb_tag, -1)) + DPRINTF(("failed to tag ipsec packet\n")); +#endif + /* * We're done with IPsec processing, transmit the packet using the * appropriate network protocol (IP or IPv6). SPD lookup will be |