@@ -889,6 +889,90 @@ static void calipso_sock_delattr(struct sock *sk)
889889 txopt_put (txopts );
890890}
891891
892+ /* request sock functions.
893+ */
894+
895+ /**
896+ * calipso_req_setattr - Add a CALIPSO option to a connection request socket
897+ * @req: the connection request socket
898+ * @doi_def: the CALIPSO DOI to use
899+ * @secattr: the specific security attributes of the socket
900+ *
901+ * Description:
902+ * Set the CALIPSO option on the given socket using the DOI definition and
903+ * security attributes passed to the function. Returns zero on success and
904+ * negative values on failure.
905+ *
906+ */
907+ static int calipso_req_setattr (struct request_sock * req ,
908+ const struct calipso_doi * doi_def ,
909+ const struct netlbl_lsm_secattr * secattr )
910+ {
911+ struct ipv6_txoptions * txopts ;
912+ struct inet_request_sock * req_inet = inet_rsk (req );
913+ struct ipv6_opt_hdr * old , * new ;
914+ struct sock * sk = sk_to_full_sk (req_to_sk (req ));
915+
916+ if (req_inet -> ipv6_opt && req_inet -> ipv6_opt -> hopopt )
917+ old = req_inet -> ipv6_opt -> hopopt ;
918+ else
919+ old = NULL ;
920+
921+ new = calipso_opt_insert (old , doi_def , secattr );
922+ if (IS_ERR (new ))
923+ return PTR_ERR (new );
924+
925+ txopts = ipv6_renew_options_kern (sk , req_inet -> ipv6_opt , IPV6_HOPOPTS ,
926+ new , new ? ipv6_optlen (new ) : 0 );
927+
928+ kfree (new );
929+
930+ if (IS_ERR (txopts ))
931+ return PTR_ERR (txopts );
932+
933+ txopts = xchg (& req_inet -> ipv6_opt , txopts );
934+ if (txopts ) {
935+ atomic_sub (txopts -> tot_len , & sk -> sk_omem_alloc );
936+ txopt_put (txopts );
937+ }
938+
939+ return 0 ;
940+ }
941+
942+ /**
943+ * calipso_req_delattr - Delete the CALIPSO option from a request socket
944+ * @reg: the request socket
945+ *
946+ * Description:
947+ * Removes the CALIPSO option from a request socket, if present.
948+ *
949+ */
950+ static void calipso_req_delattr (struct request_sock * req )
951+ {
952+ struct inet_request_sock * req_inet = inet_rsk (req );
953+ struct ipv6_opt_hdr * new ;
954+ struct ipv6_txoptions * txopts ;
955+ struct sock * sk = sk_to_full_sk (req_to_sk (req ));
956+
957+ if (!req_inet -> ipv6_opt || !req_inet -> ipv6_opt -> hopopt )
958+ return ;
959+
960+ if (calipso_opt_del (req_inet -> ipv6_opt -> hopopt , & new ))
961+ return ; /* Nothing to do */
962+
963+ txopts = ipv6_renew_options_kern (sk , req_inet -> ipv6_opt , IPV6_HOPOPTS ,
964+ new , new ? ipv6_optlen (new ) : 0 );
965+
966+ if (!IS_ERR (txopts )) {
967+ txopts = xchg (& req_inet -> ipv6_opt , txopts );
968+ if (txopts ) {
969+ atomic_sub (txopts -> tot_len , & sk -> sk_omem_alloc );
970+ txopt_put (txopts );
971+ }
972+ }
973+ kfree (new );
974+ }
975+
892976static const struct netlbl_calipso_ops ops = {
893977 .doi_add = calipso_doi_add ,
894978 .doi_free = calipso_doi_free ,
@@ -899,6 +983,8 @@ static const struct netlbl_calipso_ops ops = {
899983 .sock_getattr = calipso_sock_getattr ,
900984 .sock_setattr = calipso_sock_setattr ,
901985 .sock_delattr = calipso_sock_delattr ,
986+ .req_setattr = calipso_req_setattr ,
987+ .req_delattr = calipso_req_delattr ,
902988};
903989
904990/**
0 commit comments