Annotation of embedaddon/strongswan/src/libcharon/config/child_cfg.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2008-2019 Tobias Brunner
        !             3:  * Copyright (C) 2016 Andreas Steffen
        !             4:  * Copyright (C) 2005-2007 Martin Willi
        !             5:  * Copyright (C) 2005 Jan Hutter
        !             6:  * HSR Hochschule fuer Technik Rapperswil
        !             7:  *
        !             8:  * This program is free software; you can redistribute it and/or modify it
        !             9:  * under the terms of the GNU General Public License as published by the
        !            10:  * Free Software Foundation; either version 2 of the License, or (at your
        !            11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !            12:  *
        !            13:  * This program is distributed in the hope that it will be useful, but
        !            14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            16:  * for more details.
        !            17:  */
        !            18: 
        !            19: #include "child_cfg.h"
        !            20: 
        !            21: #include <stdint.h>
        !            22: 
        !            23: #include <daemon.h>
        !            24: 
        !            25: ENUM(action_names, ACTION_NONE, ACTION_RESTART,
        !            26:        "clear",
        !            27:        "hold",
        !            28:        "restart",
        !            29: );
        !            30: 
        !            31: /** Default replay window size, if not set using charon.replay_window */
        !            32: #define DEFAULT_REPLAY_WINDOW 32
        !            33: 
        !            34: typedef struct private_child_cfg_t private_child_cfg_t;
        !            35: 
        !            36: /**
        !            37:  * Private data of an child_cfg_t object
        !            38:  */
        !            39: struct private_child_cfg_t {
        !            40: 
        !            41:        /**
        !            42:         * Public part
        !            43:         */
        !            44:        child_cfg_t public;
        !            45: 
        !            46:        /**
        !            47:         * Number of references hold by others to this child_cfg
        !            48:         */
        !            49:        refcount_t refcount;
        !            50: 
        !            51:        /**
        !            52:         * Name of the child_cfg, used to query it
        !            53:         */
        !            54:        char *name;
        !            55: 
        !            56:        /**
        !            57:         * Options
        !            58:         */
        !            59:        child_cfg_option_t options;
        !            60: 
        !            61:        /**
        !            62:         * list for all proposals
        !            63:         */
        !            64:        linked_list_t *proposals;
        !            65: 
        !            66:        /**
        !            67:         * list for traffic selectors for my site
        !            68:         */
        !            69:        linked_list_t *my_ts;
        !            70: 
        !            71:        /**
        !            72:         * list for traffic selectors for others site
        !            73:         */
        !            74:        linked_list_t *other_ts;
        !            75: 
        !            76:        /**
        !            77:         * updown script
        !            78:         */
        !            79:        char *updown;
        !            80: 
        !            81:        /**
        !            82:         * Mode to propose for a initiated CHILD: tunnel/transport
        !            83:         */
        !            84:        ipsec_mode_t mode;
        !            85: 
        !            86:        /**
        !            87:         * action to take to start CHILD_SA
        !            88:         */
        !            89:        action_t start_action;
        !            90: 
        !            91:        /**
        !            92:         * action to take on DPD
        !            93:         */
        !            94:        action_t dpd_action;
        !            95: 
        !            96:        /**
        !            97:         * action to take on CHILD_SA close
        !            98:         */
        !            99:        action_t close_action;
        !           100: 
        !           101:        /**
        !           102:         * CHILD_SA lifetime config
        !           103:         */
        !           104:        lifetime_cfg_t lifetime;
        !           105: 
        !           106:        /**
        !           107:         * Inactivity timeout
        !           108:         */
        !           109:        uint32_t inactivity;
        !           110: 
        !           111:        /**
        !           112:         * Reqid to install CHILD_SA with
        !           113:         */
        !           114:        uint32_t reqid;
        !           115: 
        !           116:        /**
        !           117:         * Optional interface ID to use for inbound CHILD_SA
        !           118:         */
        !           119:        uint32_t if_id_in;
        !           120: 
        !           121:        /**
        !           122:         * Optional interface ID to use for outbound CHILD_SA
        !           123:         */
        !           124:        uint32_t if_id_out;
        !           125: 
        !           126:        /**
        !           127:         * Optional mark to install inbound CHILD_SA with
        !           128:         */
        !           129:        mark_t mark_in;
        !           130: 
        !           131:        /**
        !           132:         * Optional mark to install outbound CHILD_SA with
        !           133:         */
        !           134:        mark_t mark_out;
        !           135: 
        !           136:        /**
        !           137:         * Optional mark to set to packets after inbound processing
        !           138:         */
        !           139:        mark_t set_mark_in;
        !           140: 
        !           141:        /**
        !           142:         * Optional mark to set to packets after outbound processing
        !           143:         */
        !           144:        mark_t set_mark_out;
        !           145: 
        !           146:        /**
        !           147:         * Traffic Flow Confidentiality padding, if enabled
        !           148:         */
        !           149:        uint32_t tfc;
        !           150: 
        !           151:        /**
        !           152:         * Optional manually-set IPsec policy priorities
        !           153:         */
        !           154:        uint32_t manual_prio;
        !           155: 
        !           156:        /**
        !           157:         * Optional restriction of IPsec policy to a given network interface
        !           158:         */
        !           159:        char *interface;
        !           160: 
        !           161:        /**
        !           162:         * anti-replay window size
        !           163:         */
        !           164:        uint32_t replay_window;
        !           165: 
        !           166:        /**
        !           167:         * HW offload mode
        !           168:         */
        !           169:        hw_offload_t hw_offload;
        !           170: 
        !           171:        /**
        !           172:         * DS header field copy mode
        !           173:         */
        !           174:        dscp_copy_t copy_dscp;
        !           175: };
        !           176: 
        !           177: METHOD(child_cfg_t, get_name, char*,
        !           178:        private_child_cfg_t *this)
        !           179: {
        !           180:        return this->name;
        !           181: }
        !           182: 
        !           183: METHOD(child_cfg_t, has_option, bool,
        !           184:        private_child_cfg_t *this, child_cfg_option_t option)
        !           185: {
        !           186:        return this->options & option;
        !           187: }
        !           188: 
        !           189: METHOD(child_cfg_t, add_proposal, void,
        !           190:        private_child_cfg_t *this, proposal_t *proposal)
        !           191: {
        !           192:        if (proposal)
        !           193:        {
        !           194:                this->proposals->insert_last(this->proposals, proposal);
        !           195:        }
        !           196: }
        !           197: 
        !           198: CALLBACK(match_proposal, bool,
        !           199:        proposal_t *item, va_list args)
        !           200: {
        !           201:        proposal_t *proposal;
        !           202: 
        !           203:        VA_ARGS_VGET(args, proposal);
        !           204:        return item->equals(item, proposal);
        !           205: }
        !           206: 
        !           207: METHOD(child_cfg_t, get_proposals, linked_list_t*,
        !           208:        private_child_cfg_t *this, bool strip_dh)
        !           209: {
        !           210:        enumerator_t *enumerator;
        !           211:        proposal_t *current;
        !           212:        proposal_selection_flag_t flags = 0;
        !           213:        linked_list_t *proposals = linked_list_create();
        !           214: 
        !           215:        if (strip_dh)
        !           216:        {
        !           217:                flags |= PROPOSAL_SKIP_DH;
        !           218:        }
        !           219: 
        !           220:        enumerator = this->proposals->create_enumerator(this->proposals);
        !           221:        while (enumerator->enumerate(enumerator, &current))
        !           222:        {
        !           223:                current = current->clone(current, flags);
        !           224:                if (proposals->find_first(proposals, match_proposal, NULL, current))
        !           225:                {
        !           226:                        current->destroy(current);
        !           227:                        continue;
        !           228:                }
        !           229:                proposals->insert_last(proposals, current);
        !           230:        }
        !           231:        enumerator->destroy(enumerator);
        !           232: 
        !           233:        DBG2(DBG_CFG, "configured proposals: %#P", proposals);
        !           234: 
        !           235:        return proposals;
        !           236: }
        !           237: 
        !           238: METHOD(child_cfg_t, select_proposal, proposal_t*,
        !           239:        private_child_cfg_t*this, linked_list_t *proposals,
        !           240:        proposal_selection_flag_t flags)
        !           241: {
        !           242:        return proposal_select(this->proposals, proposals, flags);
        !           243: }
        !           244: 
        !           245: METHOD(child_cfg_t, add_traffic_selector, void,
        !           246:        private_child_cfg_t *this, bool local, traffic_selector_t *ts)
        !           247: {
        !           248:        if (local)
        !           249:        {
        !           250:                this->my_ts->insert_last(this->my_ts, ts);
        !           251:        }
        !           252:        else
        !           253:        {
        !           254:                this->other_ts->insert_last(this->other_ts, ts);
        !           255:        }
        !           256: }
        !           257: 
        !           258: METHOD(child_cfg_t, get_traffic_selectors, linked_list_t*,
        !           259:        private_child_cfg_t *this, bool local, linked_list_t *supplied,
        !           260:        linked_list_t *hosts, bool log)
        !           261: {
        !           262:        enumerator_t *e1, *e2;
        !           263:        traffic_selector_t *ts1, *ts2, *selected;
        !           264:        linked_list_t *result, *derived;
        !           265:        host_t *host;
        !           266: 
        !           267:        result = linked_list_create();
        !           268:        derived = linked_list_create();
        !           269:        if (local)
        !           270:        {
        !           271:                e1 = this->my_ts->create_enumerator(this->my_ts);
        !           272:        }
        !           273:        else
        !           274:        {
        !           275:                e1 = this->other_ts->create_enumerator(this->other_ts);
        !           276:        }
        !           277:        /* in a first step, replace "dynamic" TS with the host list */
        !           278:        while (e1->enumerate(e1, &ts1))
        !           279:        {
        !           280:                if (hosts && hosts->get_count(hosts))
        !           281:                {       /* set hosts if TS is dynamic or as initiator in transport mode */
        !           282:                        bool dynamic = ts1->is_dynamic(ts1),
        !           283:                                 proxy_mode = has_option(this, OPT_PROXY_MODE);
        !           284:                        if (dynamic || (this->mode == MODE_TRANSPORT && !proxy_mode &&
        !           285:                                                        !supplied))
        !           286:                        {
        !           287:                                e2 = hosts->create_enumerator(hosts);
        !           288:                                while (e2->enumerate(e2, &host))
        !           289:                                {
        !           290:                                        ts2 = ts1->clone(ts1);
        !           291:                                        if (dynamic || !host->is_anyaddr(host))
        !           292:                                        {       /* don't make regular TS larger than they were */
        !           293:                                                ts2->set_address(ts2, host);
        !           294:                                        }
        !           295:                                        derived->insert_last(derived, ts2);
        !           296:                                }
        !           297:                                e2->destroy(e2);
        !           298:                                continue;
        !           299:                        }
        !           300:                }
        !           301:                derived->insert_last(derived, ts1->clone(ts1));
        !           302:        }
        !           303:        e1->destroy(e1);
        !           304: 
        !           305:        if (log)
        !           306:        {
        !           307:                DBG2(DBG_CFG, "%s traffic selectors for %s:",
        !           308:                         supplied ? "selecting" : "proposing", local ? "us" : "other");
        !           309:        }
        !           310:        if (!supplied)
        !           311:        {
        !           312:                while (derived->remove_first(derived, (void**)&ts1) == SUCCESS)
        !           313:                {
        !           314:                        if (log)
        !           315:                        {
        !           316:                                DBG2(DBG_CFG, " %R", ts1);
        !           317:                        }
        !           318:                        result->insert_last(result, ts1);
        !           319:                }
        !           320:                derived->destroy(derived);
        !           321:        }
        !           322:        else
        !           323:        {
        !           324:                e1 = derived->create_enumerator(derived);
        !           325:                e2 = supplied->create_enumerator(supplied);
        !           326:                /* enumerate all configured/derived selectors */
        !           327:                while (e1->enumerate(e1, &ts1))
        !           328:                {
        !           329:                        /* enumerate all supplied traffic selectors */
        !           330:                        while (e2->enumerate(e2, &ts2))
        !           331:                        {
        !           332:                                selected = ts1->get_subset(ts1, ts2);
        !           333:                                if (selected)
        !           334:                                {
        !           335:                                        if (log)
        !           336:                                        {
        !           337:                                                DBG2(DBG_CFG, " config: %R, received: %R => match: %R",
        !           338:                                                         ts1, ts2, selected);
        !           339:                                        }
        !           340:                                        result->insert_last(result, selected);
        !           341:                                }
        !           342:                                else if (log)
        !           343:                                {
        !           344:                                        DBG2(DBG_CFG, " config: %R, received: %R => no match",
        !           345:                                                 ts1, ts2);
        !           346:                                }
        !           347:                        }
        !           348:                        supplied->reset_enumerator(supplied, e2);
        !           349:                }
        !           350:                e1->destroy(e1);
        !           351:                e2->destroy(e2);
        !           352: 
        !           353:                /* check if we/peer did any narrowing, raise alert */
        !           354:                e1 = derived->create_enumerator(derived);
        !           355:                e2 = result->create_enumerator(result);
        !           356:                while (e1->enumerate(e1, &ts1))
        !           357:                {
        !           358:                        if (!e2->enumerate(e2, &ts2) || !ts1->equals(ts1, ts2))
        !           359:                        {
        !           360:                                charon->bus->alert(charon->bus, ALERT_TS_NARROWED,
        !           361:                                                                   local, result, this);
        !           362:                                break;
        !           363:                        }
        !           364:                }
        !           365:                e1->destroy(e1);
        !           366:                e2->destroy(e2);
        !           367: 
        !           368:                derived->destroy_offset(derived, offsetof(traffic_selector_t, destroy));
        !           369:        }
        !           370: 
        !           371:        /* remove any redundant traffic selectors in the list */
        !           372:        e1 = result->create_enumerator(result);
        !           373:        e2 = result->create_enumerator(result);
        !           374:        while (e1->enumerate(e1, &ts1))
        !           375:        {
        !           376:                while (e2->enumerate(e2, &ts2))
        !           377:                {
        !           378:                        if (ts1 != ts2)
        !           379:                        {
        !           380:                                if (ts2->is_contained_in(ts2, ts1))
        !           381:                                {
        !           382:                                        result->remove_at(result, e2);
        !           383:                                        ts2->destroy(ts2);
        !           384:                                        result->reset_enumerator(result, e1);
        !           385:                                        break;
        !           386:                                }
        !           387:                                if (ts1->is_contained_in(ts1, ts2))
        !           388:                                {
        !           389:                                        result->remove_at(result, e1);
        !           390:                                        ts1->destroy(ts1);
        !           391:                                        break;
        !           392:                                }
        !           393:                        }
        !           394:                }
        !           395:                result->reset_enumerator(result, e2);
        !           396:        }
        !           397:        e1->destroy(e1);
        !           398:        e2->destroy(e2);
        !           399: 
        !           400:        return result;
        !           401: }
        !           402: 
        !           403: METHOD(child_cfg_t, get_updown, char*,
        !           404:        private_child_cfg_t *this)
        !           405: {
        !           406:        return this->updown;
        !           407: }
        !           408: 
        !           409: /**
        !           410:  * Applies jitter to the rekey value. Returns the new rekey value.
        !           411:  * Note: The distribution of random values is not perfect, but it
        !           412:  * should get the job done.
        !           413:  */
        !           414: static uint64_t apply_jitter(uint64_t rekey, uint64_t jitter)
        !           415: {
        !           416:        if (jitter == 0)
        !           417:        {
        !           418:                return rekey;
        !           419:        }
        !           420:        jitter = (jitter == UINT64_MAX) ? jitter : jitter + 1;
        !           421:        return rekey - jitter * (random() / (RAND_MAX + 1.0));
        !           422: }
        !           423: #define APPLY_JITTER(l) l.rekey = apply_jitter(l.rekey, l.jitter)
        !           424: 
        !           425: METHOD(child_cfg_t, get_lifetime, lifetime_cfg_t*,
        !           426:        private_child_cfg_t *this, bool jitter)
        !           427: {
        !           428:        lifetime_cfg_t *lft = malloc_thing(lifetime_cfg_t);
        !           429:        memcpy(lft, &this->lifetime, sizeof(lifetime_cfg_t));
        !           430:        if (!jitter)
        !           431:        {
        !           432:                lft->time.jitter = lft->bytes.jitter = lft->packets.jitter = 0;
        !           433:        }
        !           434:        APPLY_JITTER(lft->time);
        !           435:        APPLY_JITTER(lft->bytes);
        !           436:        APPLY_JITTER(lft->packets);
        !           437:        return lft;
        !           438: }
        !           439: 
        !           440: METHOD(child_cfg_t, get_mode, ipsec_mode_t,
        !           441:        private_child_cfg_t *this)
        !           442: {
        !           443:        return this->mode;
        !           444: }
        !           445: 
        !           446: METHOD(child_cfg_t, get_start_action, action_t,
        !           447:        private_child_cfg_t *this)
        !           448: {
        !           449:        return this->start_action;
        !           450: }
        !           451: 
        !           452: METHOD(child_cfg_t, get_hw_offload, hw_offload_t,
        !           453:        private_child_cfg_t *this)
        !           454: {
        !           455:        return this->hw_offload;
        !           456: }
        !           457: 
        !           458: METHOD(child_cfg_t, get_copy_dscp, dscp_copy_t,
        !           459:        private_child_cfg_t *this)
        !           460: {
        !           461:        return this->copy_dscp;
        !           462: }
        !           463: 
        !           464: METHOD(child_cfg_t, get_dpd_action, action_t,
        !           465:        private_child_cfg_t *this)
        !           466: {
        !           467:        return this->dpd_action;
        !           468: }
        !           469: 
        !           470: METHOD(child_cfg_t, get_close_action, action_t,
        !           471:        private_child_cfg_t *this)
        !           472: {
        !           473:        return this->close_action;
        !           474: }
        !           475: 
        !           476: METHOD(child_cfg_t, get_dh_group, diffie_hellman_group_t,
        !           477:        private_child_cfg_t *this)
        !           478: {
        !           479:        enumerator_t *enumerator;
        !           480:        proposal_t *proposal;
        !           481:        uint16_t dh_group = MODP_NONE;
        !           482: 
        !           483:        enumerator = this->proposals->create_enumerator(this->proposals);
        !           484:        while (enumerator->enumerate(enumerator, &proposal))
        !           485:        {
        !           486:                if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &dh_group, NULL))
        !           487:                {
        !           488:                        break;
        !           489:                }
        !           490:        }
        !           491:        enumerator->destroy(enumerator);
        !           492:        return dh_group;
        !           493: }
        !           494: 
        !           495: METHOD(child_cfg_t, get_inactivity, uint32_t,
        !           496:        private_child_cfg_t *this)
        !           497: {
        !           498:        return this->inactivity;
        !           499: }
        !           500: 
        !           501: METHOD(child_cfg_t, get_reqid, uint32_t,
        !           502:        private_child_cfg_t *this)
        !           503: {
        !           504:        return this->reqid;
        !           505: }
        !           506: 
        !           507: METHOD(child_cfg_t, get_if_id, uint32_t,
        !           508:        private_child_cfg_t *this, bool inbound)
        !           509: {
        !           510:        return inbound ? this->if_id_in : this->if_id_out;
        !           511: }
        !           512: 
        !           513: METHOD(child_cfg_t, get_mark, mark_t,
        !           514:        private_child_cfg_t *this, bool inbound)
        !           515: {
        !           516:        return inbound ? this->mark_in : this->mark_out;
        !           517: }
        !           518: 
        !           519: METHOD(child_cfg_t, get_set_mark, mark_t,
        !           520:        private_child_cfg_t *this, bool inbound)
        !           521: {
        !           522:        return inbound ? this->set_mark_in : this->set_mark_out;
        !           523: }
        !           524: 
        !           525: METHOD(child_cfg_t, get_tfc, uint32_t,
        !           526:        private_child_cfg_t *this)
        !           527: {
        !           528:        return this->tfc;
        !           529: }
        !           530: 
        !           531: METHOD(child_cfg_t, get_manual_prio, uint32_t,
        !           532:        private_child_cfg_t *this)
        !           533: {
        !           534:        return this->manual_prio;
        !           535: }
        !           536: 
        !           537: METHOD(child_cfg_t, get_interface, char*,
        !           538:        private_child_cfg_t *this)
        !           539: {
        !           540:        return this->interface;
        !           541: }
        !           542: 
        !           543: METHOD(child_cfg_t, get_replay_window, uint32_t,
        !           544:        private_child_cfg_t *this)
        !           545: {
        !           546:        return this->replay_window;
        !           547: }
        !           548: 
        !           549: METHOD(child_cfg_t, set_replay_window, void,
        !           550:        private_child_cfg_t *this, uint32_t replay_window)
        !           551: {
        !           552:        this->replay_window = replay_window;
        !           553: }
        !           554: 
        !           555: #define LT_PART_EQUALS(a, b) ({ a.life == b.life && a.rekey == b.rekey && a.jitter == b.jitter; })
        !           556: #define LIFETIME_EQUALS(a, b) ({ LT_PART_EQUALS(a.time, b.time) && LT_PART_EQUALS(a.bytes, b.bytes) && LT_PART_EQUALS(a.packets, b.packets); })
        !           557: 
        !           558: METHOD(child_cfg_t, equals, bool,
        !           559:        private_child_cfg_t *this, child_cfg_t *other_pub)
        !           560: {
        !           561:        private_child_cfg_t *other = (private_child_cfg_t*)other_pub;
        !           562: 
        !           563:        if (this == other)
        !           564:        {
        !           565:                return TRUE;
        !           566:        }
        !           567:        if (this->public.equals != other->public.equals)
        !           568:        {
        !           569:                return FALSE;
        !           570:        }
        !           571:        if (!this->proposals->equals_offset(this->proposals, other->proposals,
        !           572:                                                                                offsetof(proposal_t, equals)))
        !           573:        {
        !           574:                return FALSE;
        !           575:        }
        !           576:        if (!this->my_ts->equals_offset(this->my_ts, other->my_ts,
        !           577:                                                                        offsetof(traffic_selector_t, equals)))
        !           578:        {
        !           579:                return FALSE;
        !           580:        }
        !           581:        if (!this->other_ts->equals_offset(this->other_ts, other->other_ts,
        !           582:                                                                           offsetof(traffic_selector_t, equals)))
        !           583:        {
        !           584:                return FALSE;
        !           585:        }
        !           586:        return this->options == other->options &&
        !           587:                this->mode == other->mode &&
        !           588:                this->start_action == other->start_action &&
        !           589:                this->dpd_action == other->dpd_action &&
        !           590:                this->close_action == other->close_action &&
        !           591:                LIFETIME_EQUALS(this->lifetime, other->lifetime) &&
        !           592:                this->inactivity == other->inactivity &&
        !           593:                this->reqid == other->reqid &&
        !           594:                this->if_id_in == other->if_id_in &&
        !           595:                this->if_id_out == other->if_id_out &&
        !           596:                this->mark_in.value == other->mark_in.value &&
        !           597:                this->mark_in.mask == other->mark_in.mask &&
        !           598:                this->mark_out.value == other->mark_out.value &&
        !           599:                this->mark_out.mask == other->mark_out.mask &&
        !           600:                this->set_mark_in.value == other->set_mark_in.value &&
        !           601:                this->set_mark_in.mask == other->set_mark_in.mask &&
        !           602:                this->set_mark_out.value == other->set_mark_out.value &&
        !           603:                this->set_mark_out.mask == other->set_mark_out.mask &&
        !           604:                this->tfc == other->tfc &&
        !           605:                this->manual_prio == other->manual_prio &&
        !           606:                this->replay_window == other->replay_window &&
        !           607:                this->hw_offload == other->hw_offload &&
        !           608:                this->copy_dscp == other->copy_dscp &&
        !           609:                streq(this->updown, other->updown) &&
        !           610:                streq(this->interface, other->interface);
        !           611: }
        !           612: 
        !           613: METHOD(child_cfg_t, get_ref, child_cfg_t*,
        !           614:        private_child_cfg_t *this)
        !           615: {
        !           616:        ref_get(&this->refcount);
        !           617:        return &this->public;
        !           618: }
        !           619: 
        !           620: METHOD(child_cfg_t, destroy, void,
        !           621:        private_child_cfg_t *this)
        !           622: {
        !           623:        if (ref_put(&this->refcount))
        !           624:        {
        !           625:                this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
        !           626:                this->my_ts->destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy));
        !           627:                this->other_ts->destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy));
        !           628:                free(this->updown);
        !           629:                free(this->interface);
        !           630:                free(this->name);
        !           631:                free(this);
        !           632:        }
        !           633: }
        !           634: 
        !           635: /*
        !           636:  * Described in header-file
        !           637:  */
        !           638: child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data)
        !           639: {
        !           640:        private_child_cfg_t *this;
        !           641: 
        !           642:        INIT(this,
        !           643:                .public = {
        !           644:                        .get_name = _get_name,
        !           645:                        .add_traffic_selector = _add_traffic_selector,
        !           646:                        .get_traffic_selectors = _get_traffic_selectors,
        !           647:                        .add_proposal = _add_proposal,
        !           648:                        .get_proposals = _get_proposals,
        !           649:                        .select_proposal = _select_proposal,
        !           650:                        .get_updown = _get_updown,
        !           651:                        .get_mode = _get_mode,
        !           652:                        .get_start_action = _get_start_action,
        !           653:                        .get_dpd_action = _get_dpd_action,
        !           654:                        .get_close_action = _get_close_action,
        !           655:                        .get_lifetime = _get_lifetime,
        !           656:                        .get_dh_group = _get_dh_group,
        !           657:                        .get_inactivity = _get_inactivity,
        !           658:                        .get_reqid = _get_reqid,
        !           659:                        .get_if_id = _get_if_id,
        !           660:                        .get_mark = _get_mark,
        !           661:                        .get_set_mark = _get_set_mark,
        !           662:                        .get_tfc = _get_tfc,
        !           663:                        .get_manual_prio = _get_manual_prio,
        !           664:                        .get_interface = _get_interface,
        !           665:                        .get_replay_window = _get_replay_window,
        !           666:                        .set_replay_window = _set_replay_window,
        !           667:                        .has_option = _has_option,
        !           668:                        .equals = _equals,
        !           669:                        .get_ref = _get_ref,
        !           670:                        .destroy = _destroy,
        !           671:                        .get_hw_offload = _get_hw_offload,
        !           672:                        .get_copy_dscp = _get_copy_dscp,
        !           673:                },
        !           674:                .name = strdup(name),
        !           675:                .options = data->options,
        !           676:                .updown = strdupnull(data->updown),
        !           677:                .reqid = data->reqid,
        !           678:                .if_id_in = data->if_id_in,
        !           679:                .if_id_out = data->if_id_out,
        !           680:                .mode = data->mode,
        !           681:                .start_action = data->start_action,
        !           682:                .dpd_action = data->dpd_action,
        !           683:                .close_action = data->close_action,
        !           684:                .mark_in = data->mark_in,
        !           685:                .mark_out = data->mark_out,
        !           686:                .set_mark_in = data->set_mark_in,
        !           687:                .set_mark_out = data->set_mark_out,
        !           688:                .lifetime = data->lifetime,
        !           689:                .inactivity = data->inactivity,
        !           690:                .tfc = data->tfc,
        !           691:                .manual_prio = data->priority,
        !           692:                .interface = strdupnull(data->interface),
        !           693:                .refcount = 1,
        !           694:                .proposals = linked_list_create(),
        !           695:                .my_ts = linked_list_create(),
        !           696:                .other_ts = linked_list_create(),
        !           697:                .replay_window = lib->settings->get_int(lib->settings,
        !           698:                                                        "%s.replay_window", DEFAULT_REPLAY_WINDOW, lib->ns),
        !           699:                .hw_offload = data->hw_offload,
        !           700:                .copy_dscp = data->copy_dscp,
        !           701:        );
        !           702: 
        !           703:        return &this->public;
        !           704: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>